Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
Zino Holwerda | fe5b2a54ef | |
Zino Holwerda | 383f97ae93 | |
Zino Holwerda | 13e567adfb | |
Andrew Lalis | 54d7fb3fed | |
Andrew Lalis | a55bb49f1c | |
Andrew Lalis | fde75385bd | |
Andrew Lalis | 8177ad8669 |
|
@ -0,0 +1,16 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<annotationProcessing>
|
||||||
|
<profile name="Maven default annotation processors profile" enabled="true">
|
||||||
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
|
<outputRelativeToContentRoot value="true" />
|
||||||
|
<module name="HandieBot" />
|
||||||
|
</profile>
|
||||||
|
</annotationProcessing>
|
||||||
|
<bytecodeTargetLevel>
|
||||||
|
<module name="HandieBot" target="1.8" />
|
||||||
|
</bytecodeTargetLevel>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="KotlinCommonCompilerArguments">
|
||||||
|
<option name="languageVersion" value="1.1" />
|
||||||
|
<option name="apiVersion" value="1.1" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.5">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.8.5/jackson-core-2.8.5.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.8.5/jackson-core-2.8.5-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-core/2.8.5/jackson-core-2.8.5-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.5">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.8.5/jackson-databind-2.8.5.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.8.5/jackson-databind-2.8.5-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/core/jackson-databind/2.8.5/jackson-databind-2.8.5-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.fasterxml.jackson.module:jackson-module-afterburner:2.8.7">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-afterburner/2.8.7/jackson-module-afterburner-2.8.7.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-afterburner/2.8.7/jackson-module-afterburner-2.8.7-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/fasterxml/jackson/module/jackson-module-afterburner/2.8.7/jackson-module-afterburner-2.8.7-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.googlecode.soundlibs:jlayer:1.0.1-2">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/jlayer/1.0.1-2/jlayer-1.0.1-2.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/jlayer/1.0.1-2/jlayer-1.0.1-2-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/jlayer/1.0.1-2/jlayer-1.0.1-2-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.googlecode.soundlibs:mp3spi:1.9.5-2">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/mp3spi/1.9.5-2/mp3spi-1.9.5-2.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/mp3spi/1.9.5-2/mp3spi-1.9.5-2-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/mp3spi/1.9.5-2/mp3spi-1.9.5-2-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.googlecode.soundlibs:tritonus-share:0.3.7-3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/tritonus-share/0.3.7-3/tritonus-share-0.3.7-3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/tritonus-share/0.3.7-3/tritonus-share-0.3.7-3-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/googlecode/soundlibs/tritonus-share/0.3.7-3/tritonus-share-0.3.7-3-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.koloboke:koloboke-api-jdk8:1.0.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/koloboke/koloboke-api-jdk8/1.0.0/koloboke-api-jdk8-1.0.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/koloboke/koloboke-api-jdk8/1.0.0/koloboke-api-jdk8-1.0.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/koloboke/koloboke-api-jdk8/1.0.0/koloboke-api-jdk8-1.0.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.koloboke:koloboke-impl-common-jdk8:1.0.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/koloboke/koloboke-impl-common-jdk8/1.0.0/koloboke-impl-common-jdk8-1.0.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/koloboke/koloboke-impl-common-jdk8/1.0.0/koloboke-impl-common-jdk8-1.0.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/koloboke/koloboke-impl-common-jdk8/1.0.0/koloboke-impl-common-jdk8-1.0.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.sedmelluq:lavaplayer:1.2.39">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/sedmelluq/lavaplayer/1.2.39/lavaplayer-1.2.39.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/sedmelluq/lavaplayer/1.2.39/lavaplayer-1.2.39-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/sedmelluq/lavaplayer/1.2.39/lavaplayer-1.2.39-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.sedmelluq:lavaplayer-common:1.0.5">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/sedmelluq/lavaplayer-common/1.0.5/lavaplayer-common-1.0.5.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/sedmelluq/lavaplayer-common/1.0.5/lavaplayer-common-1.0.5-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/sedmelluq/lavaplayer-common/1.0.5/lavaplayer-common-1.0.5-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: com.vdurmont:emoji-java:3.2.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/vdurmont/emoji-java/3.2.0/emoji-java-3.2.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/vdurmont/emoji-java/3.2.0/emoji-java-3.2.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/com/vdurmont/emoji-java/3.2.0/emoji-java-3.2.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: commons-codec:commons-codec:1.9">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.9/commons-codec-1.9.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.9/commons-codec-1.9-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-codec/commons-codec/1.9/commons-codec-1.9-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: commons-io:commons-io:2.5">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.5/commons-io-2.5.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.5/commons-io-2.5-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-io/commons-io/2.5/commons-io-2.5-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: commons-logging:commons-logging:1.2">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.2/commons-logging-1.2.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.2/commons-logging-1.2-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/commons-logging/commons-logging/1.2/commons-logging-1.2-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: jflac:jflac:1.3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/jflac/jflac/1.3/jflac-1.3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/jflac/jflac/1.3/jflac-1.3-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/jflac/jflac/1.3/jflac-1.3-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: junit:junit:3.8.2">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/3.8.2/junit-3.8.2.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/3.8.2/junit-3.8.2-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/junit/junit/3.8.2/junit-3.8.2-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: net.iharder:base64:2.3.9">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/iharder/base64/2.3.9/base64-2.3.9.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/iharder/base64/2.3.9/base64-2.3.9-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/iharder/base64/2.3.9/base64-2.3.9-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: net.java.dev.jna:jna:4.3.0">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/java/dev/jna/jna/4.3.0/jna-4.3.0.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/java/dev/jna/jna/4.3.0/jna-4.3.0-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/java/dev/jna/jna/4.3.0/jna-4.3.0-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: net.jodah:typetools:0.4.8">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jodah/typetools/0.4.8/typetools-0.4.8.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jodah/typetools/0.4.8/typetools-0.4.8-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/net/jodah/typetools/0.4.8/typetools-0.4.8-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.apache.commons:commons-lang3:3.5">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/commons/commons-lang3/3.5/commons-lang3-3.5-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.apache.httpcomponents:httpclient:4.5.3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.3/httpclient-4.5.3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.3/httpclient-4.5.3-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpclient/4.5.3/httpclient-4.5.3-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.apache.httpcomponents:httpcore:4.4.6">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpcore/4.4.6/httpcore-4.4.6.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpcore/4.4.6/httpcore-4.4.6-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpcore/4.4.6/httpcore-4.4.6-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.apache.httpcomponents:httpmime:4.5.3">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpmime/4.5.3/httpmime-4.5.3.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpmime/4.5.3/httpmime-4.5.3-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/apache/httpcomponents/httpmime/4.5.3/httpmime-4.5.3-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.eclipse.jetty:jetty-client:9.4.3.v20170317">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-client/9.4.3.v20170317/jetty-client-9.4.3.v20170317.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-client/9.4.3.v20170317/jetty-client-9.4.3.v20170317-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-client/9.4.3.v20170317/jetty-client-9.4.3.v20170317-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.eclipse.jetty:jetty-http:9.4.3.v20170317">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-http/9.4.3.v20170317/jetty-http-9.4.3.v20170317.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-http/9.4.3.v20170317/jetty-http-9.4.3.v20170317-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-http/9.4.3.v20170317/jetty-http-9.4.3.v20170317-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.eclipse.jetty:jetty-io:9.4.3.v20170317">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-io/9.4.3.v20170317/jetty-io-9.4.3.v20170317.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-io/9.4.3.v20170317/jetty-io-9.4.3.v20170317-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-io/9.4.3.v20170317/jetty-io-9.4.3.v20170317-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.eclipse.jetty:jetty-util:9.4.3.v20170317">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-util/9.4.3.v20170317/jetty-util-9.4.3.v20170317.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-util/9.4.3.v20170317/jetty-util-9.4.3.v20170317-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/jetty-util/9.4.3.v20170317/jetty-util-9.4.3.v20170317-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.3.v20170317">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-api/9.4.3.v20170317/websocket-api-9.4.3.v20170317.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-api/9.4.3.v20170317/websocket-api-9.4.3.v20170317-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-api/9.4.3.v20170317/websocket-api-9.4.3.v20170317-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.3.v20170317">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-client/9.4.3.v20170317/websocket-client-9.4.3.v20170317.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-client/9.4.3.v20170317/websocket-client-9.4.3.v20170317-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-client/9.4.3.v20170317/websocket-client-9.4.3.v20170317-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.3.v20170317">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-common/9.4.3.v20170317/websocket-common-9.4.3.v20170317.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-common/9.4.3.v20170317/websocket-common-9.4.3.v20170317-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/eclipse/jetty/websocket/websocket-common/9.4.3.v20170317/websocket-common-9.4.3.v20170317-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.jcraft:jorbis:0.0.17">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jcraft/jorbis/0.0.17/jorbis-0.0.17.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jcraft/jorbis/0.0.17/jorbis-0.0.17-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jcraft/jorbis/0.0.17/jorbis-0.0.17-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.json:json:20140107">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20140107/json-20140107.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20140107/json-20140107-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/json/json/20140107/json-20140107-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.jsoup:jsoup:1.10.1">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jsoup/jsoup/1.10.1/jsoup-1.10.1.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jsoup/jsoup/1.10.1/jsoup-1.10.1-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/jsoup/jsoup/1.10.1/jsoup-1.10.1-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.slf4j:slf4j-api:1.7.24">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.24/slf4j-api-1.7.24.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.24/slf4j-api-1.7.24-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/slf4j/slf4j-api/1.7.24/slf4j-api-1.7.24-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,13 @@
|
||||||
|
<component name="libraryTable">
|
||||||
|
<library name="Maven: org.tritonus:tritonus-dsp:0.3.6">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/tritonus/tritonus-dsp/0.3.6/tritonus-dsp-0.3.6.jar!/" />
|
||||||
|
</CLASSES>
|
||||||
|
<JAVADOC>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/tritonus/tritonus-dsp/0.3.6/tritonus-dsp-0.3.6-javadoc.jar!/" />
|
||||||
|
</JAVADOC>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="jar://$MAVEN_REPOSITORY$/org/tritonus/tritonus-dsp/0.3.6/tritonus-dsp-0.3.6-sources.jar!/" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</component>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/HandieBot.iml" filepath="$PROJECT_DIR$/HandieBot.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,124 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,64 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.austinv11:Discord4J:2.8.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.24" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.6" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpmime:4.5.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-io:commons-io:2.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.3.v20170317" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.3.v20170317" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.3.v20170317" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.3.v20170317" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.3.v20170317" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.3.v20170317" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.3.v20170317" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.jodah:typetools:0.4.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-afterburner:2.8.7" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.java.dev.jna:jna:4.3.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.googlecode.soundlibs:mp3spi:1.9.5-2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.googlecode.soundlibs:jlayer:1.0.1-2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: junit:junit:3.8.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jcraft:jorbis:0.0.17" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: jflac:jflac:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.googlecode.soundlibs:tritonus-share:0.3.7-3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.tritonus:tritonus-dsp:0.3.6" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.vdurmont:emoji-java:3.2.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.json:json:20140107" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.koloboke:koloboke-impl-common-jdk8:1.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.koloboke:koloboke-api-jdk8:1.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.sedmelluq:lavaplayer:1.2.39" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: com.sedmelluq:lavaplayer-common:1.0.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.8.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.8.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.8.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.jsoup:jsoup:1.10.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: net.iharder:base64:2.3.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.andrewlalis:TengwarTranslatorLibrary:1.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.apis:google-api-services-youtube:v3-rev183-1.22.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.api-client:google-api-client:1.22.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.oauth-client:google-oauth-client:1.22.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.http-client:google-http-client:1.22.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.http-client:google-http-client-jackson2:1.22.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.guava:guava-jdk5:17.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.oauth-client:google-oauth-client-jetty:1.22.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.oauth-client:google-oauth-client-java6:1.22.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mortbay.jetty:jetty:6.1.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mortbay.jetty:jetty-util:6.1.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mortbay.jetty:servlet-api:2.5-20081211" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
12
pom.xml
12
pom.xml
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<groupId>com.github.andrewlalis</groupId>
|
<groupId>com.github.andrewlalis</groupId>
|
||||||
<artifactId>HandieBot</artifactId>
|
<artifactId>HandieBot</artifactId>
|
||||||
<version>1.4.0</version>
|
<version>1.5.0</version>
|
||||||
<build>
|
<build>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
|
@ -72,6 +72,16 @@
|
||||||
<artifactId>TengwarTranslatorLibrary</artifactId>
|
<artifactId>TengwarTranslatorLibrary</artifactId>
|
||||||
<version>1.3</version>
|
<version>1.3</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.apis</groupId>
|
||||||
|
<artifactId>google-api-services-youtube</artifactId>
|
||||||
|
<version>v3-rev183-1.22.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.oauth-client</groupId>
|
||||||
|
<artifactId>google-oauth-client-jetty</artifactId>
|
||||||
|
<version>1.22.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -3,6 +3,7 @@ package handiebot;
|
||||||
import handiebot.command.CommandHandler;
|
import handiebot.command.CommandHandler;
|
||||||
import handiebot.command.ReactionHandler;
|
import handiebot.command.ReactionHandler;
|
||||||
import handiebot.lavaplayer.MusicPlayer;
|
import handiebot.lavaplayer.MusicPlayer;
|
||||||
|
import handiebot.utils.FileUtil;
|
||||||
import handiebot.view.BotLog;
|
import handiebot.view.BotLog;
|
||||||
import handiebot.view.BotWindow;
|
import handiebot.view.BotWindow;
|
||||||
import sx.blah.discord.api.ClientBuilder;
|
import sx.blah.discord.api.ClientBuilder;
|
||||||
|
@ -16,6 +17,9 @@ import sx.blah.discord.handle.obj.Permissions;
|
||||||
import sx.blah.discord.util.DiscordException;
|
import sx.blah.discord.util.DiscordException;
|
||||||
import sx.blah.discord.util.RateLimitException;
|
import sx.blah.discord.util.RateLimitException;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,7 +31,14 @@ import java.util.*;
|
||||||
public class HandieBot {
|
public class HandieBot {
|
||||||
|
|
||||||
public static final String APPLICATION_NAME = "HandieBot";
|
public static final String APPLICATION_NAME = "HandieBot";
|
||||||
private static final String TOKEN = "MjgzNjUyOTg5MjEyNjg4Mzg0.C45A_Q.506b0G6my1FEFa7_YY39lxLBHUY";
|
private static final String TOKEN;
|
||||||
|
static {
|
||||||
|
TOKEN = readToken();
|
||||||
|
if (TOKEN.isEmpty()){
|
||||||
|
System.out.println("You do not have the token required to start the bot. Shutting down.");
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
private static boolean USE_GUI = true;
|
private static boolean USE_GUI = true;
|
||||||
|
|
||||||
public static final ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings");
|
public static final ResourceBundle resourceBundle = ResourceBundle.getBundle("Strings");
|
||||||
|
@ -82,7 +93,7 @@ public class HandieBot {
|
||||||
|
|
||||||
public static void main(String[] args) throws DiscordException, RateLimitException {
|
public static void main(String[] args) throws DiscordException, RateLimitException {
|
||||||
|
|
||||||
musicPlayer = new MusicPlayer();
|
//musicPlayer = new MusicPlayer();
|
||||||
|
|
||||||
List<String> argsList = Arrays.asList(args);
|
List<String> argsList = Arrays.asList(args);
|
||||||
|
|
||||||
|
@ -113,6 +124,21 @@ public class HandieBot {
|
||||||
return channel.getModifiedPermissions(client.getOurUser()).contains(permission);
|
return channel.getModifiedPermissions(client.getOurUser()).contains(permission);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the private discord token necessary to start the bot. If this fails, the bot will shut down.
|
||||||
|
* @return The string token needed to log in.
|
||||||
|
*/
|
||||||
|
private static String readToken(){
|
||||||
|
String path = FileUtil.getDataDirectory()+"token.txt";
|
||||||
|
String result = "";
|
||||||
|
try(BufferedReader reader = new BufferedReader(new FileReader(path))){
|
||||||
|
result = reader.readLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Unable to find the token file. You are unable to start the bot without this.");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Safely shuts down the bot on all guilds.
|
* Safely shuts down the bot on all guilds.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package handiebot.command;
|
package handiebot.command;
|
||||||
|
|
||||||
import handiebot.utils.DisappearingMessage;
|
|
||||||
import handiebot.utils.FileUtil;
|
import handiebot.utils.FileUtil;
|
||||||
|
import handiebot.utils.MessageUtils;
|
||||||
import handiebot.view.BotLog;
|
import handiebot.view.BotLog;
|
||||||
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
|
@ -50,7 +50,7 @@ public class CommandHandler {
|
||||||
//Create a context to give to each command's execution, so it knows what channel to reply on, etc.
|
//Create a context to give to each command's execution, so it knows what channel to reply on, etc.
|
||||||
CommandContext context = new CommandContext(user, channel, guild, args);
|
CommandContext context = new CommandContext(user, channel, guild, args);
|
||||||
if (guild != null && command != null){
|
if (guild != null && command != null){
|
||||||
DisappearingMessage.deleteMessageAfter(1000, message);
|
MessageUtils.deleteMessageAfter(1000, message);
|
||||||
Commands.executeCommand(command, context);
|
Commands.executeCommand(command, context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import java.util.List;
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
import static handiebot.HandieBot.log;
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -52,13 +53,14 @@ public class Commands {
|
||||||
public static void executeCommand(String command, CommandContext context){
|
public static void executeCommand(String command, CommandContext context){
|
||||||
for (Command cmd : commands) {
|
for (Command cmd : commands) {
|
||||||
if (cmd.getName().equals(command)){
|
if (cmd.getName().equals(command)){
|
||||||
if (cmd instanceof StaticCommand){
|
if (cmd instanceof StaticCommand &&
|
||||||
|
((context != null && cmd.canUserExecute(context.getUser(), context.getGuild())) || context == null)){
|
||||||
log.log(BotLog.TYPE.COMMAND, command+" has been issued.");
|
log.log(BotLog.TYPE.COMMAND, command+" has been issued.");
|
||||||
((StaticCommand)cmd).execute();
|
((StaticCommand)cmd).execute();
|
||||||
return;
|
return;
|
||||||
} else if (!cmd.canUserExecute(context.getUser(), context.getGuild())){
|
} else if (!cmd.canUserExecute(context.getUser(), context.getGuild())){
|
||||||
log.log(BotLog.TYPE.COMMAND, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.noPermission.log"), context.getUser().getName(), cmd.getName()));
|
log.log(BotLog.TYPE.COMMAND, context.getGuild(), MessageFormat.format(resourceBundle.getString("commands.noPermission.log"), context.getUser().getName(), cmd.getName()));
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.noPermission.message"), command));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.noPermission.message"), command), context.getChannel());
|
||||||
return;
|
return;
|
||||||
} else if (cmd instanceof ContextCommand){
|
} else if (cmd instanceof ContextCommand){
|
||||||
log.log(BotLog.TYPE.COMMAND, context.getGuild(), context.getUser().getName()+" has issued the command: "+command);
|
log.log(BotLog.TYPE.COMMAND, context.getGuild(), context.getUser().getName()+" has issued the command: "+command);
|
||||||
|
@ -100,7 +102,7 @@ public class Commands {
|
||||||
(context.getUser().getLongID() == 235439851263098880L) ||
|
(context.getUser().getLongID() == 235439851263098880L) ||
|
||||||
(permission == 0);
|
(permission == 0);
|
||||||
if (!result){
|
if (!result){
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.noPermission.subcommand"));
|
sendMessage(resourceBundle.getString("commands.noPermission.subcommand"), context.getChannel());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +1,60 @@
|
||||||
package handiebot.command;
|
package handiebot.command;
|
||||||
|
|
||||||
import handiebot.HandieBot;
|
import handiebot.command.types.ReactionListener;
|
||||||
import handiebot.view.BotLog;
|
|
||||||
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
|
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
|
||||||
import sx.blah.discord.handle.obj.IReaction;
|
|
||||||
import sx.blah.discord.handle.obj.IUser;
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
* Class which handles user reactions to songs and performs necessary actions.
|
* Class which handles user reactions to songs and performs necessary actions.
|
||||||
*/
|
*/
|
||||||
public class ReactionHandler {
|
public class ReactionHandler {
|
||||||
|
|
||||||
public static final String thumbsUp = "\uD83D\uDC4D";
|
private static List<ReactionListener> listeners = new ArrayList<>();
|
||||||
public static final String thumbsDown = "\uD83D\uDC4E";
|
private static boolean iterating = false;
|
||||||
|
private static List<ReactionListener> listenersToRemove = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* Adds a listener, so that it is notified when reaction events are received.
|
||||||
|
* @param listener The listener to add.
|
||||||
|
*/
|
||||||
|
public static void addListener(ReactionListener listener){
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a listener from the list of reaction listeners.
|
||||||
|
* @param listener The listener to remove.
|
||||||
|
*/
|
||||||
|
public static void removeListener(ReactionListener listener){
|
||||||
|
if (iterating){
|
||||||
|
listenersToRemove.add(listener);
|
||||||
|
} else {
|
||||||
|
listeners.remove(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notifies all listeners that a ReactionEvent has occurred, and calls each one's function.
|
||||||
|
* @param event The event that occurred.
|
||||||
|
*/
|
||||||
|
private static void notifyListeners(ReactionEvent event){
|
||||||
|
iterating = true;
|
||||||
|
for (ReactionListener listener : listeners){
|
||||||
|
listener.onReactionEvent(event);
|
||||||
|
}
|
||||||
|
iterating = false;
|
||||||
|
listeners.removeAll(listenersToRemove);
|
||||||
|
listenersToRemove.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Processes a reaction.
|
* Processes a reaction.
|
||||||
* @param event The reaction event to process.
|
* @param event The reaction event to process.
|
||||||
*/
|
*/
|
||||||
public static void handleReaction(ReactionEvent event){
|
public static void handleReaction(ReactionEvent event){
|
||||||
IMessage message = event.getMessage();
|
notifyListeners(event);
|
||||||
IReaction reaction = event.getReaction();
|
|
||||||
CommandContext context = new CommandContext(event.getUser(), event.getChannel(), event.getGuild(), new String[]{});
|
|
||||||
if (reaction.toString().equals(thumbsDown)){
|
|
||||||
onDownvote(context, message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* What to do if someone downvotes a song.
|
|
||||||
* If more than half of the people in the voice channel dislike the song, it will be skipped.
|
|
||||||
* If not, then the bot will tell how many more people need to downvote.
|
|
||||||
* @param context The context of the reaction.
|
|
||||||
* @param message The messages that received a reaction.
|
|
||||||
*/
|
|
||||||
private static void onDownvote(CommandContext context, IMessage message){
|
|
||||||
//Filter out reactions to previous messages.
|
|
||||||
if (message.getLongID() != HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.getPlayMessageId()){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
List<IUser> usersHere = HandieBot.musicPlayer.getVoiceChannel(context.getGuild()).getConnectedUsers();
|
|
||||||
//Remove the bot from the list of users in the voice channel.
|
|
||||||
usersHere.removeIf(user -> (user.getLongID() == HandieBot.client.getOurUser().getLongID()) ||
|
|
||||||
(user.getVoiceStateForGuild(context.getGuild()).isDeafened()) ||
|
|
||||||
(user.getVoiceStateForGuild(context.getGuild()).isSelfDeafened()));
|
|
||||||
|
|
||||||
int userCount = usersHere.size();
|
|
||||||
int userDownvotes = 0;
|
|
||||||
IReaction reaction = message.getReactionByUnicode(thumbsDown);
|
|
||||||
for (IUser user : reaction.getUsers()){
|
|
||||||
if (usersHere.contains(user)){
|
|
||||||
userDownvotes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (userDownvotes > (userCount/2)){
|
|
||||||
log.log(BotLog.TYPE.MUSIC, context.getGuild(), "Users voted to skip the current song.");
|
|
||||||
HandieBot.musicPlayer.skipTrack(context.getGuild());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
package handiebot.command;
|
||||||
|
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author: Zino Holwerda
|
||||||
|
* Date: 7/13/2017.
|
||||||
|
*/
|
||||||
|
public class SelectionController implements MouseListener {
|
||||||
|
|
||||||
|
|
||||||
|
public SelectionController() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseClicked(MouseEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mousePressed(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited(MouseEvent e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,6 +9,7 @@ import java.text.MessageFormat;
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
import static handiebot.HandieBot.log;
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -29,10 +30,10 @@ public class SetPrefixCommand extends ContextCommand {
|
||||||
CommandHandler.PREFIXES.put(context.getGuild(), context.getArgs()[0]);
|
CommandHandler.PREFIXES.put(context.getGuild(), context.getArgs()[0]);
|
||||||
CommandHandler.saveGuildPrefixes();
|
CommandHandler.saveGuildPrefixes();
|
||||||
String response = MessageFormat.format(resourceBundle.getString("commands.command.setPrefix.changed"), context.getArgs()[0]);
|
String response = MessageFormat.format(resourceBundle.getString("commands.command.setPrefix.changed"), context.getArgs()[0]);
|
||||||
context.getChannel().sendMessage(response);
|
sendMessage(response, context.getChannel());
|
||||||
log.log(BotLog.TYPE.INFO, response);
|
log.log(BotLog.TYPE.INFO, response);
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.setPrefix.noPrefixError"));
|
sendMessage(resourceBundle.getString("commands.command.setPrefix.noPrefixError"), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package handiebot.command.commands.interfaceActions;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
|
||||||
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author: Zino Holwerda
|
||||||
|
* Date: 7/14/2017.
|
||||||
|
*/
|
||||||
|
public class PlaylistAction extends AbstractAction {
|
||||||
|
|
||||||
|
private static final String DEFAULT_SOURCE_CHOICE_LABEL = "Available Playlists";
|
||||||
|
|
||||||
|
public PlaylistAction() {
|
||||||
|
super(resourceBundle.getString("action.menu.playlist"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
JFrame editPlaylist = new JFrame(resourceBundle.getString("action.menu.playlist"));
|
||||||
|
editPlaylist.setLayout(new BorderLayout(5,5));
|
||||||
|
|
||||||
|
JPanel topSide = new JPanel(new FlowLayout());
|
||||||
|
|
||||||
|
JPanel leftSide = new JPanel(new BorderLayout(5,5));
|
||||||
|
JLabel sourceLabel = new JLabel(DEFAULT_SOURCE_CHOICE_LABEL);
|
||||||
|
JList<String> playlistList = new JList<>();
|
||||||
|
leftSide.add(sourceLabel, BorderLayout.NORTH);
|
||||||
|
JScrollPane scrollPane = new JScrollPane(playlistList);
|
||||||
|
scrollPane.setPreferredSize(new Dimension(200, 200));
|
||||||
|
leftSide.add(scrollPane, BorderLayout.SOUTH);
|
||||||
|
topSide.add(leftSide);
|
||||||
|
|
||||||
|
JPanel rightSide = new JPanel(new BorderLayout(5,5));
|
||||||
|
JButton addButton = new JButton(resourceBundle.getString("action.menu.playlist.add"));
|
||||||
|
rightSide.add(addButton, BorderLayout.NORTH);
|
||||||
|
addButton.addActionListener(null);
|
||||||
|
JButton deleteButton = new JButton(resourceBundle.getString("action.menu.playlist.delete"));
|
||||||
|
rightSide.add(deleteButton, BorderLayout.AFTER_LINE_ENDS);
|
||||||
|
deleteButton.addActionListener(null);
|
||||||
|
JButton editButton = new JButton(resourceBundle.getString("action.menu.playlist.edit"));
|
||||||
|
rightSide.add(editButton, BorderLayout.AFTER_LAST_LINE);
|
||||||
|
editButton.addActionListener(null);
|
||||||
|
topSide.add(rightSide);
|
||||||
|
editPlaylist.add(topSide, BorderLayout.PAGE_START);
|
||||||
|
|
||||||
|
JPanel bottomSide = new JPanel();
|
||||||
|
bottomSide.add(new JScrollPane(playlistList));
|
||||||
|
editPlaylist.add(bottomSide, BorderLayout.PAGE_END);
|
||||||
|
|
||||||
|
editPlaylist.pack();
|
||||||
|
editPlaylist.setLocationRelativeTo(null);
|
||||||
|
editPlaylist.setVisible(true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package handiebot.command.commands.interfaceActions.PlaylistActions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author: Zino
|
||||||
|
* Date: 7/14/2017.
|
||||||
|
*/
|
||||||
|
public class DeletePlaylistAction {
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package handiebot.command.commands.interfaceActions.PlaylistActions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author: Zino
|
||||||
|
* Date: 7/14/2017.
|
||||||
|
*/
|
||||||
|
public class EditPlaylistAction {
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package handiebot.command.commands.interfaceActions.PlaylistActions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Author: Zino
|
||||||
|
* Date: 7/14/2017.
|
||||||
|
*/
|
||||||
|
public class NewPlaylistAction {
|
||||||
|
}
|
|
@ -2,12 +2,14 @@ package handiebot.command.commands.misc;
|
||||||
|
|
||||||
import handiebot.command.CommandContext;
|
import handiebot.command.CommandContext;
|
||||||
import handiebot.command.types.ContextCommand;
|
import handiebot.command.types.ContextCommand;
|
||||||
|
import handiebot.utils.MessageUtils;
|
||||||
import net.agspace.TengwarImageGenerator;
|
import net.agspace.TengwarImageGenerator;
|
||||||
import net.agspace.Translator;
|
import net.agspace.Translator;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -24,12 +26,13 @@ public class TengwarCommand extends ContextCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
if (context.getArgs().length == 0){
|
if (context.getArgs().length == 0){
|
||||||
context.getChannel().sendMessage(this.getUsage(context.getGuild()));
|
sendMessage(this.getUsage(context.getGuild()), context.getChannel());
|
||||||
} else if (context.getArgs().length >= 2){
|
} else if (context.getArgs().length >= 2){
|
||||||
String input = readTextFromArgs(context.getArgs());
|
String input = MessageUtils.getTextFromArgs(context.getArgs(), 1);
|
||||||
if (context.getArgs()[0].equalsIgnoreCase("to")){
|
if (context.getArgs()[0].equalsIgnoreCase("to")){
|
||||||
String result = Translator.translateToTengwar(input);
|
String result = Translator.translateToTengwar(input);
|
||||||
try {
|
try {
|
||||||
|
//TODO: replace with rate-limited send method.
|
||||||
context.getChannel().sendFile("Raw text: `" +result+'`', TengwarImageGenerator.generateImage(result,
|
context.getChannel().sendFile("Raw text: `" +result+'`', TengwarImageGenerator.generateImage(result,
|
||||||
600,
|
600,
|
||||||
24f,
|
24f,
|
||||||
|
@ -40,18 +43,11 @@ public class TengwarCommand extends ContextCommand {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else if (context.getArgs()[0].equalsIgnoreCase("from")){
|
} else if (context.getArgs()[0].equalsIgnoreCase("from")){
|
||||||
context.getChannel().sendMessage(Translator.translateToEnglish(input));
|
sendMessage(Translator.translateToEnglish(input), context.getChannel());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(this.getUsage(context.getGuild()));
|
sendMessage(this.getUsage(context.getGuild()), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String readTextFromArgs(String[] args){
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
for (int i = 1; i < args.length; i++){
|
|
||||||
sb.append(args[i]).append(' ');
|
|
||||||
}
|
|
||||||
return sb.toString().trim();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
package handiebot.command.commands.music;
|
package handiebot.command.commands.music;
|
||||||
|
|
||||||
|
import com.google.api.services.youtube.model.Video;
|
||||||
import handiebot.HandieBot;
|
import handiebot.HandieBot;
|
||||||
import handiebot.command.CommandContext;
|
import handiebot.command.CommandContext;
|
||||||
|
import handiebot.command.ReactionHandler;
|
||||||
|
import handiebot.command.reactionListeners.YoutubePlayListener;
|
||||||
import handiebot.command.types.ContextCommand;
|
import handiebot.command.types.ContextCommand;
|
||||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||||
|
import handiebot.utils.MessageUtils;
|
||||||
|
import handiebot.utils.YoutubeSearch;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
import static handiebot.utils.YoutubeSearch.WATCH_URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -17,7 +27,7 @@ public class PlayCommand extends ContextCommand {
|
||||||
|
|
||||||
public PlayCommand() {
|
public PlayCommand() {
|
||||||
super("play",
|
super("play",
|
||||||
"[URL]",
|
"[URL|QUERY]",
|
||||||
resourceBundle.getString("commands.command.play.description"),
|
resourceBundle.getString("commands.command.play.description"),
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
@ -27,12 +37,24 @@ public class PlayCommand extends ContextCommand {
|
||||||
if (context.getArgs() == null || context.getArgs().length == 0){
|
if (context.getArgs() == null || context.getArgs().length == 0){
|
||||||
HandieBot.musicPlayer.playQueue(context.getGuild());
|
HandieBot.musicPlayer.playQueue(context.getGuild());
|
||||||
} else {
|
} else {
|
||||||
|
//Check if an actual URL is used, and if not, create a youtube request.
|
||||||
|
if (context.getArgs()[0].startsWith("http")) {
|
||||||
try {
|
try {
|
||||||
HandieBot.musicPlayer.addToQueue(context.getGuild(), new UnloadedTrack(context.getArgs()[0]), context.getUser());
|
HandieBot.musicPlayer.addToQueue(context.getGuild(), new UnloadedTrack(context.getArgs()[0]), context.getUser());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.play.songAddError"), context.getArgs()[0]));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.play.songAddError"), context.getArgs()[0]), context.getChannel());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
//Construct a Youtube song choice.
|
||||||
|
List<Video> videos = YoutubeSearch.query(MessageUtils.getTextFromArgs(context.getArgs(), 0));
|
||||||
|
if (videos != null) {
|
||||||
|
List<String> urls = new ArrayList<>(videos.size());
|
||||||
|
videos.forEach((video) -> urls.add(WATCH_URL+video.getId()));
|
||||||
|
IMessage message = YoutubeSearch.displayChoicesDialog(videos, context.getChannel());
|
||||||
|
ReactionHandler.addListener(new YoutubePlayListener(message, context.getUser(), urls));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,29 @@
|
||||||
package handiebot.command.commands.music;
|
package handiebot.command.commands.music;
|
||||||
|
|
||||||
|
import com.google.api.services.youtube.model.Video;
|
||||||
import handiebot.HandieBot;
|
import handiebot.HandieBot;
|
||||||
import handiebot.command.CommandContext;
|
import handiebot.command.CommandContext;
|
||||||
import handiebot.command.CommandHandler;
|
import handiebot.command.CommandHandler;
|
||||||
|
import handiebot.command.ReactionHandler;
|
||||||
|
import handiebot.command.reactionListeners.YoutubePlaylistAddListener;
|
||||||
import handiebot.command.types.ContextCommand;
|
import handiebot.command.types.ContextCommand;
|
||||||
import handiebot.lavaplayer.playlist.Playlist;
|
import handiebot.lavaplayer.playlist.Playlist;
|
||||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||||
import handiebot.utils.DisappearingMessage;
|
import handiebot.utils.MessageUtils;
|
||||||
|
import handiebot.utils.YoutubeSearch;
|
||||||
import handiebot.view.BotLog;
|
import handiebot.view.BotLog;
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
import sx.blah.discord.util.RequestBuffer;
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
import static handiebot.HandieBot.log;
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
import static handiebot.utils.YoutubeSearch.WATCH_URL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -31,7 +38,7 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
"\t`create <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.create")+"\n" +
|
"\t`create <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.create")+"\n" +
|
||||||
"\t`delete <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.delete")+"\n" +
|
"\t`delete <PLAYLIST>` - "+resourceBundle.getString("commands.command.playlist.description.delete")+"\n" +
|
||||||
"\t`show [PLAYLIST]` - "+resourceBundle.getString("commands.command.playlist.description.show")+"\n" +
|
"\t`show [PLAYLIST]` - "+resourceBundle.getString("commands.command.playlist.description.show")+"\n" +
|
||||||
"\t`add <PLAYLIST> <URL> [URL]...` - "+resourceBundle.getString("commands.command.playlist.description.add")+"\n" +
|
"\t`add <PLAYLIST> <URL URL...|SEARCHTEXT, SEARCHTEXT...>` - "+resourceBundle.getString("commands.command.playlist.description.add")+"\n" +
|
||||||
"\t`remove <PLAYLIST> <SONGINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.remove")+"\n" +
|
"\t`remove <PLAYLIST> <SONGINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.remove")+"\n" +
|
||||||
"\t`rename <PLAYLIST> <NEWNAME>` - "+resourceBundle.getString("commands.command.playlist.description.rename")+"\n" +
|
"\t`rename <PLAYLIST> <NEWNAME>` - "+resourceBundle.getString("commands.command.playlist.description.rename")+"\n" +
|
||||||
"\t`move <PLAYLIST> <OLDINDEX> <NEWINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.move")+"\n" +
|
"\t`move <PLAYLIST> <OLDINDEX> <NEWINDEX>` - "+resourceBundle.getString("commands.command.playlist.description.move")+"\n" +
|
||||||
|
@ -82,7 +89,8 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
* @param channel The channel to show the error message in.
|
* @param channel The channel to show the error message in.
|
||||||
*/
|
*/
|
||||||
private void incorrectMainArg(IChannel channel){
|
private void incorrectMainArg(IChannel channel){
|
||||||
new DisappearingMessage(channel, MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.incorrectMainArg"), this.getUsage(channel.getGuild())), 5000);
|
IMessage message = sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.incorrectMainArg"), this.getUsage(channel.getGuild())), channel);
|
||||||
|
MessageUtils.deleteMessageAfter(5000, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,9 +107,9 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
}
|
}
|
||||||
playlist.save();
|
playlist.save();
|
||||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.log"), playlist.getName(), playlist.getTrackCount()));
|
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.log"), playlist.getName(), playlist.getTrackCount()));
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.message"), playlist.getName(), this.getPrefixedName(context.getGuild()), playlist.getName()));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.createdPlaylist.message"), playlist.getName(), this.getPrefixedName(context.getGuild()), playlist.getName()), context.getChannel());
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.createPlaylistName"));
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.createPlaylistName"), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,13 +125,13 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
boolean success = f.delete();
|
boolean success = f.delete();
|
||||||
if (success){
|
if (success){
|
||||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.log"), context.getArgs()[1]));
|
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.log"), context.getArgs()[1]));
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.message"), context.getArgs()[1]));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.delete.message"), context.getArgs()[1]), context.getChannel());
|
||||||
} else {
|
} else {
|
||||||
log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.delete.log"), context.getArgs()[1]));
|
log.log(BotLog.TYPE.ERROR, MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.delete.log"), context.getArgs()[1]));
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.delete.message"));
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.delete.message"), context.getChannel());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.deletePlaylistName"));
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.deletePlaylistName"), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,14 +145,14 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
return;
|
return;
|
||||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||||
playlist.load();
|
playlist.load();
|
||||||
context.getChannel().sendMessage(playlist.toString());
|
sendMessage(playlist.toString(), context.getChannel());
|
||||||
} else {
|
} else {
|
||||||
List<String> playlists = Playlist.getAvailablePlaylists();
|
List<String> playlists = Playlist.getAvailablePlaylists();
|
||||||
StringBuilder sb = new StringBuilder("**Playlists:**\n");
|
StringBuilder sb = new StringBuilder("**Playlists:**\n");
|
||||||
for (String playlist : playlists) {
|
for (String playlist : playlists) {
|
||||||
sb.append(playlist).append('\n');
|
sb.append(playlist).append('\n');
|
||||||
}
|
}
|
||||||
context.getChannel().sendMessage(sb.toString());
|
sendMessage(sb.toString(), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,18 +166,30 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
return;
|
return;
|
||||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||||
playlist.load();
|
playlist.load();
|
||||||
|
if (context.getArgs()[2].startsWith("http")){
|
||||||
|
//These are songs, so add them immediately.
|
||||||
for (int i = 2; i < context.getArgs().length; i++){
|
for (int i = 2; i < context.getArgs().length; i++){
|
||||||
playlist.loadTrack(context.getArgs()[i]);
|
playlist.loadTrack(context.getArgs()[i]);
|
||||||
RequestBuffer.request(() -> context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.message"), playlist.getName()))).get();
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.message"), playlist.getName()), context.getChannel());
|
||||||
}
|
}
|
||||||
playlist.save();
|
playlist.save();
|
||||||
context.getChannel().sendMessage(playlist.toString());
|
sendMessage(playlist.toString(), context.getChannel());
|
||||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.log"), playlist.getName()));
|
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.add.log"), playlist.getName()));
|
||||||
} else {
|
} else {
|
||||||
if (context.getArgs().length == 1){
|
//This is a youtube search query.
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.addNameNeeded"), getPlaylistShowString(context)));
|
List<Video> videos = YoutubeSearch.query(MessageUtils.getTextFromArgs(context.getArgs(), 2));
|
||||||
|
if (videos != null) {
|
||||||
|
List<String> urls = new ArrayList<>(videos.size());
|
||||||
|
videos.forEach((video) -> urls.add(WATCH_URL+video.getId()));
|
||||||
|
IMessage message = YoutubeSearch.displayChoicesDialog(videos, context.getChannel());
|
||||||
|
ReactionHandler.addListener(new YoutubePlaylistAddListener(message, context.getUser(), urls, playlist));
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.addUrlNeeded"));
|
if (context.getArgs().length == 1){
|
||||||
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.addNameNeeded"), getPlaylistShowString(context)), context.getChannel());
|
||||||
|
} else {
|
||||||
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.addUrlNeeded"), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -185,11 +205,11 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
Playlist playlist = new Playlist(context.getArgs()[1]);
|
Playlist playlist = new Playlist(context.getArgs()[1]);
|
||||||
playlist.load();
|
playlist.load();
|
||||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.log"), playlist.getName()));
|
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.log"), playlist.getName()));
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.message"), playlist.getName()));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.play.message"), playlist.getName()), context.getChannel());
|
||||||
HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.setPlaylist(playlist);
|
HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.setPlaylist(playlist);
|
||||||
HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.nextTrack();
|
HandieBot.musicPlayer.getMusicManager(context.getGuild()).scheduler.nextTrack();
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playPlaylistNeeded"), getPlaylistShowString(context)));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playPlaylistNeeded"), getPlaylistShowString(context)), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,15 +224,15 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
File f = new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[1].replace(" ", "_")+".txt");
|
File f = new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[1].replace(" ", "_")+".txt");
|
||||||
boolean success = f.renameTo(new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[2].replace(" ", "_")+".txt"));
|
boolean success = f.renameTo(new File(System.getProperty("user.home")+"/.handiebot/playlist/"+context.getArgs()[2].replace(" ", "_")+".txt"));
|
||||||
if (success){
|
if (success){
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.rename.message"), context.getArgs()[1], context.getArgs()[2]));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.rename.message"), context.getArgs()[1], context.getArgs()[2]), context.getChannel());
|
||||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.rename.log"), context.getArgs()[1], context.getArgs()[2]));
|
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.playlist.rename.log"), context.getArgs()[1], context.getArgs()[2]));
|
||||||
} else {
|
} else {
|
||||||
String response = MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.renameError"), context.getArgs()[1], context.getArgs()[2]);
|
String response = MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.renameError"), context.getArgs()[1], context.getArgs()[2]);
|
||||||
context.getChannel().sendMessage(response);
|
sendMessage(response, context.getChannel());
|
||||||
log.log(BotLog.TYPE.ERROR, response);
|
log.log(BotLog.TYPE.ERROR, response);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.renameBadArgs"));
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.renameBadArgs"), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,17 +251,17 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
UnloadedTrack track = playlist.getTracks().get(index);
|
UnloadedTrack track = playlist.getTracks().get(index);
|
||||||
playlist.removeTrack(track);
|
playlist.removeTrack(track);
|
||||||
playlist.save();
|
playlist.save();
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.remove.message"), track.getTitle(), playlist.getName()));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.remove.message"), track.getTitle(), playlist.getName()), context.getChannel());
|
||||||
log.log(BotLog.TYPE.MUSIC, MessageFormat.format(resourceBundle.getString("commands.command.playlist.remove.log"), track.getTitle(), playlist.getName()));
|
log.log(BotLog.TYPE.MUSIC, MessageFormat.format(resourceBundle.getString("commands.command.playlist.remove.log"), track.getTitle(), playlist.getName()));
|
||||||
} catch (IndexOutOfBoundsException | NumberFormatException e){
|
} catch (IndexOutOfBoundsException | NumberFormatException e){
|
||||||
String response = MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.removeError"), playlist.getName());
|
String response = MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.removeError"), playlist.getName());
|
||||||
context.getChannel().sendMessage(response);
|
sendMessage(response, context.getChannel());
|
||||||
log.log(BotLog.TYPE.ERROR, response);
|
log.log(BotLog.TYPE.ERROR, response);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.removeBadArgs"));
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.removeBadArgs"), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +281,7 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
oldIndex = Integer.parseInt(context.getArgs()[2])-1;
|
oldIndex = Integer.parseInt(context.getArgs()[2])-1;
|
||||||
newIndex = Integer.parseInt(context.getArgs()[3])-1;
|
newIndex = Integer.parseInt(context.getArgs()[3])-1;
|
||||||
} catch (NumberFormatException e){
|
} catch (NumberFormatException e){
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.moveIndexError"));
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.moveIndexError"), context.getChannel());
|
||||||
}
|
}
|
||||||
UnloadedTrack track;
|
UnloadedTrack track;
|
||||||
if ((oldIndex > -1 && oldIndex < playlist.getTrackCount()) &&
|
if ((oldIndex > -1 && oldIndex < playlist.getTrackCount()) &&
|
||||||
|
@ -269,13 +289,13 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
track = playlist.getTracks().remove(oldIndex);
|
track = playlist.getTracks().remove(oldIndex);
|
||||||
playlist.getTracks().add(newIndex, track);
|
playlist.getTracks().add(newIndex, track);
|
||||||
playlist.save();
|
playlist.save();
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.move.message"), track.getTitle(), oldIndex + 1, newIndex + 1));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.move.message"), track.getTitle(), oldIndex + 1, newIndex + 1), context.getChannel());
|
||||||
log.log(BotLog.TYPE.MUSIC, MessageFormat.format(resourceBundle.getString("commands.command.playlist.move.log"), track.getTitle(), oldIndex + 1, newIndex + 1));
|
log.log(BotLog.TYPE.MUSIC, MessageFormat.format(resourceBundle.getString("commands.command.playlist.move.log"), track.getTitle(), oldIndex + 1, newIndex + 1));
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.moveInvalidIndex"), oldIndex, newIndex));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.moveInvalidIndex"), oldIndex, newIndex), context.getChannel());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(resourceBundle.getString("commands.command.playlist.error.moveBadArgs"));
|
sendMessage(resourceBundle.getString("commands.command.playlist.error.moveBadArgs"), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,7 +309,8 @@ public class PlaylistCommand extends ContextCommand {
|
||||||
if (Playlist.playlistExists(context.getArgs()[1])){
|
if (Playlist.playlistExists(context.getArgs()[1])){
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
new DisappearingMessage(context.getChannel(), MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playlistDoesNotExist"), getPlaylistShowString(context)), 3000);
|
IMessage message = sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.playlist.error.playlistDoesNotExist"), getPlaylistShowString(context)), context.getChannel());
|
||||||
|
MessageUtils.deleteMessageAfter(3000, message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.text.MessageFormat;
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
import static handiebot.HandieBot.log;
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -42,11 +43,12 @@ public class QueueCommand extends ContextCommand {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ("save"):
|
case ("save"):
|
||||||
|
//TODO: add some error messages so users know how to use this.
|
||||||
if (context.getArgs().length == 2 && Commands.hasPermission(context, 8)) {
|
if (context.getArgs().length == 2 && Commands.hasPermission(context, 8)) {
|
||||||
Playlist p = HandieBot.musicPlayer.getAllSongsInQueue(context.getGuild());
|
Playlist p = HandieBot.musicPlayer.getAllSongsInQueue(context.getGuild());
|
||||||
p.setName(context.getArgs()[1]);
|
p.setName(context.getArgs()[1]);
|
||||||
p.save();
|
p.save();
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.queue.save.message"), p.getTrackCount(), p.getName()));
|
sendMessage(MessageFormat.format(resourceBundle.getString("commands.command.queue.save.message"), p.getTrackCount(), p.getName()), context.getChannel());
|
||||||
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.queue.save.log"), p.getName()));
|
log.log(BotLog.TYPE.INFO, MessageFormat.format(resourceBundle.getString("commands.command.queue.save.log"), p.getName()));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -8,6 +8,7 @@ import handiebot.command.types.ContextCommand;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -28,7 +29,7 @@ public class RepeatCommand extends ContextCommand {
|
||||||
boolean shouldRepeat = (context.getArgs()[0].toLowerCase().equals("true"));
|
boolean shouldRepeat = (context.getArgs()[0].toLowerCase().equals("true"));
|
||||||
HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat);
|
HandieBot.musicPlayer.setRepeat(context.getGuild(), shouldRepeat);
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("player.getRepeat"), HandieBot.musicPlayer.isRepeating(context.getGuild())));
|
sendMessage(MessageFormat.format(resourceBundle.getString("player.getRepeat"), HandieBot.musicPlayer.isRepeating(context.getGuild())), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import handiebot.command.types.ContextCommand;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -28,7 +29,7 @@ public class ShuffleCommand extends ContextCommand {
|
||||||
boolean shouldShuffle = (context.getArgs()[0].toLowerCase().equals("true"));
|
boolean shouldShuffle = (context.getArgs()[0].toLowerCase().equals("true"));
|
||||||
HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle);
|
HandieBot.musicPlayer.setShuffle(context.getGuild(), shouldShuffle);
|
||||||
} else {
|
} else {
|
||||||
context.getChannel().sendMessage(MessageFormat.format(resourceBundle.getString("player.getShuffle"), HandieBot.musicPlayer.isShuffling(context.getGuild())));
|
sendMessage(MessageFormat.format(resourceBundle.getString("player.getShuffle"), HandieBot.musicPlayer.isShuffling(context.getGuild())), context.getChannel());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis & Zino Holwerda
|
||||||
* Contains all Commands which can be executed from a Discord server or the Console.
|
* Contains all Commands which can be executed from a Discord server or the Console.
|
||||||
*/
|
*/
|
||||||
package handiebot.command.commands;
|
package handiebot.command.commands;
|
|
@ -7,6 +7,7 @@ import handiebot.command.types.ContextCommand;
|
||||||
import sx.blah.discord.handle.obj.IPrivateChannel;
|
import sx.blah.discord.handle.obj.IPrivateChannel;
|
||||||
|
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -24,7 +25,6 @@ public class HelpCommand extends ContextCommand {
|
||||||
@Override
|
@Override
|
||||||
public void execute(CommandContext context) {
|
public void execute(CommandContext context) {
|
||||||
IPrivateChannel pm = context.getUser().getOrCreatePMChannel();
|
IPrivateChannel pm = context.getUser().getOrCreatePMChannel();
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder("HandieBot Commands:\n");
|
StringBuilder sb = new StringBuilder("HandieBot Commands:\n");
|
||||||
for (Command cmd : Commands.commands){
|
for (Command cmd : Commands.commands){
|
||||||
StringBuilder commandText = new StringBuilder();
|
StringBuilder commandText = new StringBuilder();
|
||||||
|
@ -36,13 +36,12 @@ public class HelpCommand extends ContextCommand {
|
||||||
}
|
}
|
||||||
commandText.append("`\n").append(cmd.getDescription()).append("\n\n");
|
commandText.append("`\n").append(cmd.getDescription()).append("\n\n");
|
||||||
if (sb.length() + commandText.length() > 2000){
|
if (sb.length() + commandText.length() > 2000){
|
||||||
pm.sendMessage(sb.toString());
|
sendMessage(sb.toString(), pm);
|
||||||
sb = commandText;
|
sb = commandText;
|
||||||
} else {
|
} else {
|
||||||
sb.append(commandText);
|
sb.append(commandText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sendMessage(sb.toString(), pm);
|
||||||
pm.sendMessage(sb.toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
package handiebot.command.reactionListeners;
|
||||||
|
|
||||||
|
import handiebot.HandieBot;
|
||||||
|
import handiebot.command.ReactionHandler;
|
||||||
|
import handiebot.command.types.ReactionListener;
|
||||||
|
import handiebot.view.BotLog;
|
||||||
|
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
import sx.blah.discord.handle.obj.IReaction;
|
||||||
|
import sx.blah.discord.handle.obj.IUser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static handiebot.HandieBot.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Listen for downvotes on the most recently played song title.
|
||||||
|
*/
|
||||||
|
public class DownvoteListener implements ReactionListener {
|
||||||
|
|
||||||
|
private static final String thumbsDown = "\uD83D\uDC4E";
|
||||||
|
|
||||||
|
private final IMessage message;
|
||||||
|
|
||||||
|
public DownvoteListener(IMessage message){
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReactionEvent(ReactionEvent event) {
|
||||||
|
if (event.getReaction().toString().equals(thumbsDown)) {
|
||||||
|
IMessage message = event.getMessage();
|
||||||
|
//Filter out reactions to previous messages.
|
||||||
|
if (message.getLongID() != this.message.getLongID()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<IUser> usersHere = HandieBot.musicPlayer.getVoiceChannel(event.getGuild()).getConnectedUsers();
|
||||||
|
//Remove the bot from the list of users in the voice channel.
|
||||||
|
usersHere.removeIf(user -> (user.getLongID() == HandieBot.client.getOurUser().getLongID()) ||
|
||||||
|
(user.getVoiceStateForGuild(event.getGuild()).isDeafened()) ||
|
||||||
|
(user.getVoiceStateForGuild(event.getGuild()).isSelfDeafened()));
|
||||||
|
|
||||||
|
int userCount = usersHere.size();
|
||||||
|
int userDownvotes = 0;
|
||||||
|
IReaction reaction = message.getReactionByUnicode(thumbsDown);
|
||||||
|
for (IUser user : reaction.getUsers()) {
|
||||||
|
if (usersHere.contains(user)) {
|
||||||
|
userDownvotes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (userDownvotes > (userCount / 2)) {
|
||||||
|
log.log(BotLog.TYPE.MUSIC, event.getGuild(), "Users voted to skip the current song.");
|
||||||
|
HandieBot.musicPlayer.skipTrack(event.getGuild());
|
||||||
|
ReactionHandler.removeListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
package handiebot.command.reactionListeners;
|
||||||
|
|
||||||
|
import handiebot.command.ReactionHandler;
|
||||||
|
import handiebot.command.types.ReactionListener;
|
||||||
|
import handiebot.view.BotLog;
|
||||||
|
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
import sx.blah.discord.handle.obj.IUser;
|
||||||
|
import sx.blah.discord.util.RequestBuffer;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static handiebot.HandieBot.log;
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Interface for youtube search results choices. A new instance of this listener is created every time a youtube
|
||||||
|
* query is shown, and is unique for each user.
|
||||||
|
*/
|
||||||
|
public abstract class YoutubeChoiceListener implements ReactionListener {
|
||||||
|
|
||||||
|
protected final IMessage message;//The message generated that this listener should attach to.
|
||||||
|
protected final IUser user;//The user who needs to make a decision.
|
||||||
|
protected final List<String> urls;//The list of URLs to display information about.
|
||||||
|
protected static final long timeout = 30000;//Time until the choice times out and deletes itself.
|
||||||
|
|
||||||
|
//These are just the raw characters for the numbers 1 - 5.
|
||||||
|
private static final String[] choices = {
|
||||||
|
"1⃣",
|
||||||
|
"2⃣",
|
||||||
|
"3⃣",
|
||||||
|
"4⃣",
|
||||||
|
"5⃣"
|
||||||
|
};
|
||||||
|
|
||||||
|
public YoutubeChoiceListener(IMessage message, IUser user, List<String> urls){
|
||||||
|
this.message = message;
|
||||||
|
this.user = user;
|
||||||
|
this.urls = urls;
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
sleep(timeout);
|
||||||
|
} catch (InterruptedException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (!message.isDeleted()){
|
||||||
|
log.log(BotLog.TYPE.MUSIC, message.getGuild(), "Youtube Choice timed out.");
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReactionEvent(ReactionEvent event) {
|
||||||
|
if ((event.getMessage().getLongID() == this.message.getLongID()) &&
|
||||||
|
(this.user.getLongID() == event.getUser().getLongID())){
|
||||||
|
for (int i = 0; i < choices.length; i++){
|
||||||
|
if (event.getReaction().toString().equals(choices[i])){
|
||||||
|
onChoice(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to delete the large, unwieldy message and remove the listener for this set of videos.
|
||||||
|
*/
|
||||||
|
private void cleanup(){
|
||||||
|
RequestBuffer.request(message::delete);
|
||||||
|
ReactionHandler.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* What to do when a choice is made.
|
||||||
|
* @param choice An integer value from 0 to 4, describing which choice the player has chosen.
|
||||||
|
*/
|
||||||
|
protected abstract void onChoice(int choice);
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
package handiebot.command.reactionListeners;
|
||||||
|
|
||||||
|
import handiebot.HandieBot;
|
||||||
|
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||||
|
import handiebot.view.BotLog;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
import sx.blah.discord.handle.obj.IUser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static handiebot.HandieBot.log;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Specific Listener for choices in the Play command, where songs chosen are added to the active queue.
|
||||||
|
*/
|
||||||
|
public class YoutubePlayListener extends YoutubeChoiceListener {
|
||||||
|
//TODO: Externalize strings
|
||||||
|
public YoutubePlayListener(IMessage message, IUser user, List<String> urls) {
|
||||||
|
super(message, user, urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onChoice(int choice) {
|
||||||
|
try {
|
||||||
|
HandieBot.musicPlayer.addToQueue(message.getGuild(), new UnloadedTrack(urls.get(choice)), this.user);
|
||||||
|
log.log(BotLog.TYPE.MUSIC, message.getGuild(), this.user.getName()+" chose item "+(choice+1)+" from the Youtube query.");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package handiebot.command.reactionListeners;
|
||||||
|
|
||||||
|
import handiebot.lavaplayer.playlist.Playlist;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
import sx.blah.discord.handle.obj.IUser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Specific Listener for adding songs to a playlist that must be saved.
|
||||||
|
*/
|
||||||
|
public class YoutubePlaylistAddListener extends YoutubeChoiceListener {
|
||||||
|
//TODO: externalize strings
|
||||||
|
private Playlist playlist;
|
||||||
|
|
||||||
|
public YoutubePlaylistAddListener(IMessage message, IUser user, List<String> urls, Playlist playlist) {
|
||||||
|
super(message, user, urls);
|
||||||
|
this.playlist = playlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onChoice(int choice) {
|
||||||
|
this.playlist.loadTrack(this.urls.get(choice));
|
||||||
|
this.playlist.save();
|
||||||
|
sendMessage("Added song to *"+this.playlist.getName()+"*.", message.getChannel());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Package for listeners of reactions, such as in-text menus.
|
||||||
|
*/
|
||||||
|
package handiebot.command.reactionListeners;
|
|
@ -0,0 +1,13 @@
|
||||||
|
package handiebot.command.types;
|
||||||
|
|
||||||
|
import sx.blah.discord.handle.impl.events.guild.channel.message.reaction.ReactionEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Interface for objects that require reaction events.
|
||||||
|
*/
|
||||||
|
public interface ReactionListener {
|
||||||
|
|
||||||
|
public void onReactionEvent(ReactionEvent event);
|
||||||
|
|
||||||
|
}
|
|
@ -6,13 +6,10 @@ import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||||
import handiebot.command.Commands;
|
import handiebot.command.Commands;
|
||||||
import handiebot.lavaplayer.playlist.Playlist;
|
import handiebot.lavaplayer.playlist.Playlist;
|
||||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||||
import handiebot.utils.DisappearingMessage;
|
import handiebot.utils.MessageUtils;
|
||||||
import handiebot.utils.Pastebin;
|
import handiebot.utils.Pastebin;
|
||||||
import handiebot.view.BotLog;
|
import handiebot.view.BotLog;
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
import sx.blah.discord.handle.obj.*;
|
||||||
import sx.blah.discord.handle.obj.IGuild;
|
|
||||||
import sx.blah.discord.handle.obj.IUser;
|
|
||||||
import sx.blah.discord.handle.obj.IVoiceChannel;
|
|
||||||
import sx.blah.discord.util.EmbedBuilder;
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
|
@ -23,6 +20,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
import static handiebot.HandieBot.log;
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -128,7 +126,7 @@ public class MusicPlayer {
|
||||||
getMusicManager(guild).scheduler.setRepeat(value);
|
getMusicManager(guild).scheduler.setRepeat(value);
|
||||||
String message = MessageFormat.format(resourceBundle.getString("player.setRepeat"), getMusicManager(guild).scheduler.isRepeating());
|
String message = MessageFormat.format(resourceBundle.getString("player.setRepeat"), getMusicManager(guild).scheduler.isRepeating());
|
||||||
log.log(BotLog.TYPE.MUSIC, guild, message);
|
log.log(BotLog.TYPE.MUSIC, guild, message);
|
||||||
getChatChannel(guild).sendMessage(":repeat: "+message);
|
sendMessage(":repeat: "+message, getChatChannel(guild));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,7 +155,7 @@ public class MusicPlayer {
|
||||||
getMusicManager(guild).scheduler.setShuffle(value);
|
getMusicManager(guild).scheduler.setShuffle(value);
|
||||||
String message = MessageFormat.format(resourceBundle.getString("player.setShuffle"), getMusicManager(guild).scheduler.isShuffling());
|
String message = MessageFormat.format(resourceBundle.getString("player.setShuffle"), getMusicManager(guild).scheduler.isShuffling());
|
||||||
log.log(BotLog.TYPE.MUSIC, guild, message);
|
log.log(BotLog.TYPE.MUSIC, guild, message);
|
||||||
getChatChannel(guild).sendMessage(":twisted_rightwards_arrows: "+message);
|
sendMessage(":twisted_rightwards_arrows: "+message, getChatChannel(guild));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -176,14 +174,15 @@ public class MusicPlayer {
|
||||||
List<UnloadedTrack> tracks = getMusicManager(guild).scheduler.queueList();
|
List<UnloadedTrack> tracks = getMusicManager(guild).scheduler.queueList();
|
||||||
if (tracks.size() == 0) {
|
if (tracks.size() == 0) {
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
getChatChannel(guild).sendMessage(MessageFormat.format(resourceBundle.getString("player.queueEmpty"), Commands.get("play").getUsage()));
|
sendMessage(MessageFormat.format(resourceBundle.getString("player.queueEmpty"), Commands.get("play").getUsage()), getChatChannel(guild));
|
||||||
} else {
|
} else {
|
||||||
if (tracks.size() > 10 && showAll) {
|
if (tracks.size() > 10 && showAll) {
|
||||||
String result = Pastebin.paste("Current queue for discord server: "+guild.getName()+".", getMusicManager(guild).scheduler.getActivePlaylist().toString());
|
String result = Pastebin.paste("Current queue for discord server: "+guild.getName()+".", getMusicManager(guild).scheduler.getActivePlaylist().toString());
|
||||||
if (result != null && result.startsWith("https://pastebin.com/")){
|
if (result != null && result.startsWith("https://pastebin.com/")){
|
||||||
log.log(BotLog.TYPE.INFO, guild, MessageFormat.format(resourceBundle.getString("player.queueUploaded"), result));
|
log.log(BotLog.TYPE.INFO, guild, MessageFormat.format(resourceBundle.getString("player.queueUploaded"), result));
|
||||||
//Only display the pastebin link for 10 minutes.
|
//Only display the pastebin link for 10 minutes.
|
||||||
new DisappearingMessage(getChatChannel(guild), MessageFormat.format(resourceBundle.getString("player.pastebinLink"), result), 600000);
|
IMessage message = sendMessage(MessageFormat.format(resourceBundle.getString("player.pastebinLink"), result), getChatChannel(guild));
|
||||||
|
MessageUtils.deleteMessageAfter(600000, message);
|
||||||
} else {
|
} else {
|
||||||
log.log(BotLog.TYPE.ERROR, guild, MessageFormat.format(resourceBundle.getString("player.pastebinError"), result));
|
log.log(BotLog.TYPE.ERROR, guild, MessageFormat.format(resourceBundle.getString("player.pastebinError"), result));
|
||||||
}
|
}
|
||||||
|
@ -220,16 +219,13 @@ public class MusicPlayer {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
if (timeUntilPlay > 0) {
|
if (timeUntilPlay > 0) {
|
||||||
sb.append(MessageFormat.format(resourceBundle.getString("player.addedToQueue"), user.getName(), track.getTitle()));
|
sb.append(MessageFormat.format(resourceBundle.getString("player.addedToQueue"), user.getName(), track.getTitle()));
|
||||||
}
|
sb.append(String.format("\nTime until play: %d min, %02d sec",
|
||||||
//If there's some tracks in the queue, get the time until this one plays.
|
|
||||||
if (timeUntilPlay > 0){
|
|
||||||
sb.append(String.format("\nTime until play: %d min, %d sec",
|
|
||||||
TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay),
|
TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay),
|
||||||
TimeUnit.MILLISECONDS.toSeconds(timeUntilPlay) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay))
|
TimeUnit.MILLISECONDS.toSeconds(timeUntilPlay) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeUntilPlay))
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
if (sb.length() > 0) {
|
if (sb.length() > 0) {
|
||||||
getChatChannel(guild).sendMessage(sb.toString());
|
sendMessage(sb.toString(), getChatChannel(guild));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,10 +233,11 @@ public class MusicPlayer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If possible, try to begin playing from the track scheduler's queue.
|
* If possible, try to begin playing from the track scheduler's queue.
|
||||||
|
* @param guild The guild to play music on.
|
||||||
*/
|
*/
|
||||||
public void playQueue(IGuild guild){
|
public void playQueue(IGuild guild){
|
||||||
if (getMusicManager(guild).scheduler.getActivePlaylist().getTrackCount() == 0){
|
if (getMusicManager(guild).scheduler.getActivePlaylist().getTrackCount() == 0){
|
||||||
getChatChannel(guild).sendMessage(resourceBundle.getString("player.playQueueEmpty"));
|
sendMessage(resourceBundle.getString("player.playQueueEmpty"), getChatChannel(guild));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IVoiceChannel vc = this.getVoiceChannel(guild);
|
IVoiceChannel vc = this.getVoiceChannel(guild);
|
||||||
|
@ -250,18 +247,23 @@ public class MusicPlayer {
|
||||||
getMusicManager(guild).scheduler.nextTrack();
|
getMusicManager(guild).scheduler.nextTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the queue for a specified guild.
|
||||||
|
* @param guild The guild to clear the queue for.
|
||||||
|
*/
|
||||||
public void clearQueue(IGuild guild){
|
public void clearQueue(IGuild guild){
|
||||||
getMusicManager(guild).scheduler.clearQueue();
|
getMusicManager(guild).scheduler.clearQueue();
|
||||||
getChatChannel(guild).sendMessage(resourceBundle.getString("player.queueCleared"));
|
sendMessage(resourceBundle.getString("player.queueCleared"), getChatChannel(guild));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips the current track.
|
* Skips the current track.
|
||||||
|
* @param guild The guild to skip the track for.
|
||||||
*/
|
*/
|
||||||
public void skipTrack(IGuild guild){
|
public void skipTrack(IGuild guild){
|
||||||
String message = resourceBundle.getString("player.skippingCurrent");
|
String message = resourceBundle.getString("player.skippingCurrent");
|
||||||
log.log(BotLog.TYPE.MUSIC, guild, message);
|
log.log(BotLog.TYPE.MUSIC, guild, message);
|
||||||
getChatChannel(guild).sendMessage(":track_next: "+message);
|
sendMessage(":track_next: "+message, getChatChannel(guild));
|
||||||
getMusicManager(guild).scheduler.nextTrack();
|
getMusicManager(guild).scheduler.nextTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,7 +274,7 @@ public class MusicPlayer {
|
||||||
public void stop(IGuild guild){
|
public void stop(IGuild guild){
|
||||||
getMusicManager(guild).scheduler.stop();
|
getMusicManager(guild).scheduler.stop();
|
||||||
String message = resourceBundle.getString("player.musicStopped");
|
String message = resourceBundle.getString("player.musicStopped");
|
||||||
getChatChannel(guild).sendMessage(":stop_button: "+message);
|
sendMessage(":stop_button: "+message, getChatChannel(guild));
|
||||||
log.log(BotLog.TYPE.MUSIC, guild, message);
|
log.log(BotLog.TYPE.MUSIC, guild, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
import com.sedmelluq.discord.lavaplayer.track.AudioTrackEndReason;
|
||||||
import handiebot.HandieBot;
|
import handiebot.HandieBot;
|
||||||
|
import handiebot.command.ReactionHandler;
|
||||||
|
import handiebot.command.reactionListeners.DownvoteListener;
|
||||||
import handiebot.lavaplayer.playlist.Playlist;
|
import handiebot.lavaplayer.playlist.Playlist;
|
||||||
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
import handiebot.lavaplayer.playlist.UnloadedTrack;
|
||||||
import handiebot.view.BotLog;
|
import handiebot.view.BotLog;
|
||||||
|
@ -13,13 +15,14 @@ import sx.blah.discord.handle.obj.IChannel;
|
||||||
import sx.blah.discord.handle.obj.IGuild;
|
import sx.blah.discord.handle.obj.IGuild;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
import sx.blah.discord.handle.obj.IVoiceChannel;
|
import sx.blah.discord.handle.obj.IVoiceChannel;
|
||||||
import sx.blah.discord.util.RequestBuffer;
|
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
import static handiebot.HandieBot.log;
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static handiebot.utils.MessageUtils.addReaction;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis
|
||||||
|
@ -34,7 +37,6 @@ public class TrackScheduler extends AudioEventAdapter {
|
||||||
private final AudioPlayer player;
|
private final AudioPlayer player;
|
||||||
|
|
||||||
private Playlist activePlaylist;
|
private Playlist activePlaylist;
|
||||||
private long activePlayMessageId;
|
|
||||||
|
|
||||||
private boolean repeat = true;
|
private boolean repeat = true;
|
||||||
private boolean shuffle = false;
|
private boolean shuffle = false;
|
||||||
|
@ -65,10 +67,6 @@ public class TrackScheduler extends AudioEventAdapter {
|
||||||
return this.activePlaylist;
|
return this.activePlaylist;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getPlayMessageId(){
|
|
||||||
return this.activePlayMessageId;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the queue.
|
* Clears the queue.
|
||||||
*/
|
*/
|
||||||
|
@ -195,10 +193,10 @@ public class TrackScheduler extends AudioEventAdapter {
|
||||||
log.log(BotLog.TYPE.MUSIC, this.guild, MessageFormat.format(resourceBundle.getString("trackSchedule.trackStarted"), track.getInfo().title));
|
log.log(BotLog.TYPE.MUSIC, this.guild, MessageFormat.format(resourceBundle.getString("trackSchedule.trackStarted"), track.getInfo().title));
|
||||||
List<IChannel> channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase());
|
List<IChannel> channels = this.guild.getChannelsByName(MusicPlayer.CHANNEL_NAME.toLowerCase());
|
||||||
if (channels.size() > 0){
|
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()));
|
IMessage message = sendMessage(MessageFormat.format(":arrow_forward: "+resourceBundle.getString("trackSchedule.nowPlaying"), track.getInfo().title, new UnloadedTrack(track).getFormattedDuration()), channels.get(0));
|
||||||
this.activePlayMessageId = message.getLongID();
|
addReaction(message, ":thumbsup:");
|
||||||
RequestBuffer.request(() -> message.addReaction(":thumbsup:")).get();
|
addReaction(message, ":thumbsdown:");
|
||||||
RequestBuffer.request(() -> message.addReaction(":thumbsdown:")).get();
|
ReactionHandler.addListener(new DownvoteListener(message));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,67 +0,0 @@
|
||||||
package handiebot.utils;
|
|
||||||
|
|
||||||
import handiebot.HandieBot;
|
|
||||||
import handiebot.view.BotLog;
|
|
||||||
import sx.blah.discord.handle.obj.IChannel;
|
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
|
||||||
import sx.blah.discord.handle.obj.Permissions;
|
|
||||||
import sx.blah.discord.util.RequestBuffer;
|
|
||||||
|
|
||||||
import static handiebot.HandieBot.log;
|
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Andrew Lalis
|
|
||||||
* Creates a message on a channel that will disappear after some time.
|
|
||||||
*/
|
|
||||||
public class DisappearingMessage extends Thread implements Runnable {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new disappearing message that times out after some time.
|
|
||||||
* @param channel The channel to write the message in.
|
|
||||||
* @param message The message content.
|
|
||||||
* @param timeout How long until the message is deleted.
|
|
||||||
*/
|
|
||||||
public DisappearingMessage(IChannel channel, String message, long timeout){
|
|
||||||
IMessage sentMessage = channel.sendMessage(message);
|
|
||||||
try {
|
|
||||||
sleep(timeout);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if (canDelete(sentMessage))
|
|
||||||
RequestBuffer.request(sentMessage::delete);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Deletes a message after a set amount of time.
|
|
||||||
* @param timeout The delay until deletion, in milliseconds.
|
|
||||||
* @param message The message to delete.
|
|
||||||
*/
|
|
||||||
public static void deleteMessageAfter(long timeout, IMessage message){
|
|
||||||
new Thread(() -> {
|
|
||||||
try {
|
|
||||||
sleep(timeout);
|
|
||||||
} catch (InterruptedException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if (canDelete(message))
|
|
||||||
RequestBuffer.request(message::delete);
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check to see if it is possible to delete a message before doing so.
|
|
||||||
* @param message The message that may be deleted.
|
|
||||||
* @return True if it is safe to delete, false otherwise.
|
|
||||||
*/
|
|
||||||
private static boolean canDelete(IMessage message){
|
|
||||||
if (HandieBot.hasPermission(Permissions.MANAGE_MESSAGES, message.getChannel())){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
log.log(BotLog.TYPE.ERROR, message.getGuild(), resourceBundle.getString("log.deleteMessageError"));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
package handiebot.utils;
|
||||||
|
|
||||||
|
import handiebot.HandieBot;
|
||||||
|
import handiebot.view.BotLog;
|
||||||
|
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||||
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
import sx.blah.discord.handle.obj.Permissions;
|
||||||
|
import sx.blah.discord.util.RequestBuffer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
|
||||||
|
import static handiebot.HandieBot.log;
|
||||||
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
import static java.lang.Thread.sleep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Creates a message on a channel that will disappear after some time.
|
||||||
|
*/
|
||||||
|
public class MessageUtils {
|
||||||
|
|
||||||
|
private MessageUtils(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a message to a channel safely, using a request buffer.
|
||||||
|
* @param content The string content of the message.
|
||||||
|
* @param channel The channel to send the message on.
|
||||||
|
* @return The message object that was sent.
|
||||||
|
*/
|
||||||
|
public static IMessage sendMessage(String content, IChannel channel){
|
||||||
|
return RequestBuffer.request(() -> (IMessage)channel.sendMessage(content)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends an embed object to a channel safely, using a request buffer.
|
||||||
|
* @param embed The content of the message.
|
||||||
|
* @param channel The channel to send the message on.
|
||||||
|
* @return The message object that was sent.
|
||||||
|
*/
|
||||||
|
public static IMessage sendMessage(EmbedObject embed, IChannel channel){
|
||||||
|
return RequestBuffer.request(() -> (IMessage)channel.sendMessage(embed)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a file object to a channel safely, using a request buffer.
|
||||||
|
* @param file The file to send.
|
||||||
|
* @param channel The channel to send the message on.
|
||||||
|
* @return The message that was sent, or null if the file could not be found.
|
||||||
|
*/
|
||||||
|
public static IMessage sendFile(File file, IChannel channel){
|
||||||
|
return RequestBuffer.request(() -> {
|
||||||
|
IMessage msg = null;
|
||||||
|
try {
|
||||||
|
msg = channel.sendFile(file);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return msg;
|
||||||
|
}).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a reaction to a message safely, using the request buffer.
|
||||||
|
* @param message The message to add a reaction to.
|
||||||
|
* @param reaction The reaction to add, in string format.
|
||||||
|
*/
|
||||||
|
public static void addReaction(IMessage message, String reaction){
|
||||||
|
RequestBuffer.request(() -> message.addReaction(reaction)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a message after a set amount of time.
|
||||||
|
* @param timeout The delay until deletion, in milliseconds.
|
||||||
|
* @param message The message to delete.
|
||||||
|
*/
|
||||||
|
public static void deleteMessageAfter(long timeout, IMessage message){
|
||||||
|
new Thread(() -> {
|
||||||
|
try {
|
||||||
|
sleep(timeout);
|
||||||
|
} catch (InterruptedException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (canDelete(message))
|
||||||
|
RequestBuffer.request(message::delete);
|
||||||
|
}).start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check to see if it is possible to delete a message before doing so.
|
||||||
|
* @param message The message that may be deleted.
|
||||||
|
* @return True if it is safe to delete, false otherwise.
|
||||||
|
*/
|
||||||
|
private static boolean canDelete(IMessage message){
|
||||||
|
if (HandieBot.hasPermission(Permissions.MANAGE_MESSAGES, message.getChannel())){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
log.log(BotLog.TYPE.ERROR, message.getGuild(), resourceBundle.getString("log.deleteMessageError"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a number into one or more emojis.
|
||||||
|
* @param number The number to convert.
|
||||||
|
* @return A string of emojis.
|
||||||
|
*/
|
||||||
|
public static String getNumberEmoji(int number){
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
while (number > 0){
|
||||||
|
int digit = number % 10;
|
||||||
|
number /= 10;
|
||||||
|
sb.append(getDigitEmoji(digit));
|
||||||
|
if (number > 0){
|
||||||
|
sb.append(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the 'emoji' for a specific digit. If the digit given is not one digit, zero is used.
|
||||||
|
* @param digit The digit to convert.
|
||||||
|
* @return A String representation of the emoji.
|
||||||
|
*/
|
||||||
|
private static String getDigitEmoji(int digit){
|
||||||
|
switch (digit){
|
||||||
|
case 1:
|
||||||
|
return ":one:";
|
||||||
|
case 2:
|
||||||
|
return ":two:";
|
||||||
|
case 3:
|
||||||
|
return ":three:";
|
||||||
|
case 4:
|
||||||
|
return ":four:";
|
||||||
|
case 5:
|
||||||
|
return ":five:";
|
||||||
|
case 6:
|
||||||
|
return ":six:";
|
||||||
|
case 7:
|
||||||
|
return ":seven:";
|
||||||
|
case 8:
|
||||||
|
return ":eight:";
|
||||||
|
case 9:
|
||||||
|
return ":nine:";
|
||||||
|
default:
|
||||||
|
return ":zero:";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a space-separated list of words from a given index until the end of an arguments list.
|
||||||
|
* @param args The args list, as it is given from a command context.
|
||||||
|
* @param firstWordIndex The index of the first word to read as text.
|
||||||
|
* @return A string of all the words combined, with spaces between each one, just as they would appear in the
|
||||||
|
* user's actual input string.
|
||||||
|
*/
|
||||||
|
public static String getTextFromArgs(String[] args, int firstWordIndex){
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = firstWordIndex; i < args.length; i++){
|
||||||
|
sb.append(args[i]);
|
||||||
|
if (i < args.length-1){
|
||||||
|
sb.append(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,213 @@
|
||||||
|
package handiebot.utils;
|
||||||
|
|
||||||
|
import com.google.api.client.auth.oauth2.Credential;
|
||||||
|
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
|
||||||
|
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
|
||||||
|
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
|
||||||
|
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
|
||||||
|
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
|
||||||
|
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
|
||||||
|
import com.google.api.client.http.HttpTransport;
|
||||||
|
import com.google.api.client.json.JsonFactory;
|
||||||
|
import com.google.api.client.json.jackson2.JacksonFactory;
|
||||||
|
import com.google.api.client.util.store.FileDataStoreFactory;
|
||||||
|
import com.google.api.services.youtube.YouTube;
|
||||||
|
import com.google.api.services.youtube.YouTubeScopes;
|
||||||
|
import com.google.api.services.youtube.model.SearchListResponse;
|
||||||
|
import com.google.api.services.youtube.model.SearchResult;
|
||||||
|
import com.google.api.services.youtube.model.Video;
|
||||||
|
import com.google.api.services.youtube.model.VideoListResponse;
|
||||||
|
import com.google.common.base.Joiner;
|
||||||
|
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||||
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.text.NumberFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import static handiebot.HandieBot.APPLICATION_NAME;
|
||||||
|
import static handiebot.utils.MessageUtils.addReaction;
|
||||||
|
import static handiebot.utils.MessageUtils.sendMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrew Lalis
|
||||||
|
* Class to query Youtube Data API for results to searches, and return these in a nice list.
|
||||||
|
*/
|
||||||
|
public class YoutubeSearch {
|
||||||
|
//TODO: Externalize Strings
|
||||||
|
private static final String KEY = "AIzaSyAjYuxCYBCuZCNvW4w573LQ-jw5UKL64G8";
|
||||||
|
private static final int NUMBER_OF_VIDEOS_RETURNED = 5;
|
||||||
|
|
||||||
|
public static final String WATCH_URL = "https://www.youtube.com/watch?v=";
|
||||||
|
|
||||||
|
private static final File DATA_STORE_DIR = new File(FileUtil.getDataDirectory()+"googleData/");
|
||||||
|
private static FileDataStoreFactory DATA_STORE_FACTORY;
|
||||||
|
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
|
||||||
|
private static HttpTransport HTTP_TRANSPORT;
|
||||||
|
|
||||||
|
private static final List<String> SCOPES = Arrays.asList(YouTubeScopes.YOUTUBE_READONLY);
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
try {
|
||||||
|
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
|
||||||
|
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
|
||||||
|
} catch (GeneralSecurityException | IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
HTTP_TRANSPORT = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an authorized Credential object.
|
||||||
|
* @return an authorized Credential object.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static Credential authorize() throws IOException {
|
||||||
|
// Load client secrets.
|
||||||
|
InputStream in = YoutubeSearch.class.getClassLoader().getResourceAsStream("client_secret.json");
|
||||||
|
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
|
||||||
|
|
||||||
|
// Build flow and trigger user authorization request.
|
||||||
|
GoogleAuthorizationCodeFlow flow =
|
||||||
|
new GoogleAuthorizationCodeFlow.Builder(
|
||||||
|
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
|
||||||
|
.setDataStoreFactory(DATA_STORE_FACTORY)
|
||||||
|
.setAccessType("offline")
|
||||||
|
.build();
|
||||||
|
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build and return an authorized API client service, such as a YouTube
|
||||||
|
* Data API client service.
|
||||||
|
* @return an authorized API client service
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public static YouTube getYouTubeService() throws IOException {
|
||||||
|
Credential credential = authorize();
|
||||||
|
return new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
|
||||||
|
.setApplicationName(APPLICATION_NAME)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query Youtube Data API for a list of videos matching a given string.
|
||||||
|
* @param searchString The string to use for the search.
|
||||||
|
* @return A List of SearchResult objects which contain data about each video.
|
||||||
|
*/
|
||||||
|
public static List<Video> query(String searchString){
|
||||||
|
try {
|
||||||
|
YouTube youtube = getYouTubeService();
|
||||||
|
YouTube.Search.List search = youtube.search().list("id,snippet");
|
||||||
|
search.setKey(KEY);
|
||||||
|
search.setQ(searchString);
|
||||||
|
search.setType("video");
|
||||||
|
search.setFields("items(id/videoId)");
|
||||||
|
search.setMaxResults((long)NUMBER_OF_VIDEOS_RETURNED);
|
||||||
|
|
||||||
|
SearchListResponse searchResponse = search.execute();
|
||||||
|
List<SearchResult> results = searchResponse.getItems();
|
||||||
|
List<String> videoIds = new ArrayList<>();
|
||||||
|
|
||||||
|
if (results != null){
|
||||||
|
for (SearchResult searchResult : results){
|
||||||
|
videoIds.add(searchResult.getId().getVideoId());
|
||||||
|
}
|
||||||
|
Joiner stringJoiner = Joiner.on(',');
|
||||||
|
String videosId = stringJoiner.join(videoIds);
|
||||||
|
YouTube.Videos.List listVideosRequest = youtube.videos().list("snippet,statistics,contentDetails").setId(videosId);
|
||||||
|
VideoListResponse listResponse = listVideosRequest.execute();
|
||||||
|
|
||||||
|
return listResponse.getItems();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (GoogleJsonResponseException e) {
|
||||||
|
System.err.println("There was a service error: " + e.getDetails().getCode() + " : "
|
||||||
|
+ e.getDetails().getMessage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an embed object to display.
|
||||||
|
* @param results The list of videos to use to generate an embed object.
|
||||||
|
* @return A fully assembled embedded object.
|
||||||
|
*/
|
||||||
|
public static EmbedObject createEmbed(List<Video> results){
|
||||||
|
EmbedBuilder builder = new EmbedBuilder();
|
||||||
|
if (results != null) {
|
||||||
|
builder.withTitle("Showing the first " + NUMBER_OF_VIDEOS_RETURNED + " results from YouTube.com");
|
||||||
|
builder.withColor(Color.red);
|
||||||
|
for (int i = 0; i < results.size(); i++) {
|
||||||
|
Video video = results.get(i);
|
||||||
|
String views = NumberFormat.getNumberInstance(Locale.US).format(video.getStatistics().getViewCount());
|
||||||
|
String duration = video.getContentDetails().getDuration()
|
||||||
|
.replace("PT", "")
|
||||||
|
.replace("H", ":")
|
||||||
|
.replace("M", ":")
|
||||||
|
.replace("S", "");
|
||||||
|
String[] components = duration.split(":");
|
||||||
|
int hours, minutes, seconds;
|
||||||
|
String formattedTime = "Unknown";
|
||||||
|
if (components.length == 2){
|
||||||
|
minutes = Integer.parseInt(components[0]);
|
||||||
|
seconds = Integer.parseInt(components[1]);
|
||||||
|
formattedTime = String.format("%d:%02d", minutes, seconds);
|
||||||
|
} else if (components.length == 3){
|
||||||
|
hours = Integer.parseInt(components[0]);
|
||||||
|
minutes = Integer.parseInt(components[1]);
|
||||||
|
seconds = Integer.parseInt(components[2]);
|
||||||
|
formattedTime = String.format("%d:%02d:%02d", hours, minutes, seconds);
|
||||||
|
}
|
||||||
|
String channelName = video.getSnippet().getChannelTitle();
|
||||||
|
double likeDislikeRatio = (double)video.getStatistics().getLikeCount().longValue() / (double)video.getStatistics().getDislikeCount().longValue();
|
||||||
|
builder.appendField(MessageUtils.getNumberEmoji(i+1) + video.getSnippet().getTitle(),
|
||||||
|
":signal_strength: " + views +
|
||||||
|
"\t:watch: " + formattedTime +
|
||||||
|
"\t:copyright: "+ channelName +
|
||||||
|
"\t:arrow_up_down: "+ String.format("%.2f", likeDislikeRatio) +
|
||||||
|
"\n"+ WATCH_URL + video.getId(),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
builder.withFooterText("Please add a reaction to select a song, or cancel. Choice times out in 30 seconds.");
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the first five results from a youtube search, and adds reactions so that a user may choose an option.
|
||||||
|
* @param videos The list of videos, returned from calling {@code query}.
|
||||||
|
* @param channel The channel to display the dialog in.
|
||||||
|
*/
|
||||||
|
public static IMessage displayChoicesDialog(List<Video> videos, IChannel channel){
|
||||||
|
EmbedObject e = YoutubeSearch.createEmbed(videos);
|
||||||
|
IMessage message = sendMessage(e, channel);
|
||||||
|
List<String> urls = new ArrayList<>(videos.size());
|
||||||
|
videos.forEach((video) -> urls.add(WATCH_URL + video.getId()));
|
||||||
|
addReaction(message, ":one:");
|
||||||
|
addReaction(message, ":two:");
|
||||||
|
addReaction(message, ":three:");
|
||||||
|
addReaction(message, ":four:");
|
||||||
|
addReaction(message, ":five:");
|
||||||
|
addReaction(message, ":x:");
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,18 +1,29 @@
|
||||||
package handiebot.view;
|
package handiebot.view;
|
||||||
|
|
||||||
import handiebot.HandieBot;
|
import handiebot.HandieBot;
|
||||||
|
import handiebot.command.SelectionController;
|
||||||
|
import handiebot.lavaplayer.playlist.Playlist;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis & Zino Holwerda
|
||||||
* This class inherits JFrame and simplifies the creation of a window.
|
* This class inherits JFrame and simplifies the creation of a window.
|
||||||
*/
|
*/
|
||||||
public class BotWindow extends JFrame {
|
public class BotWindow extends JFrame {
|
||||||
|
@ -22,7 +33,6 @@ public class BotWindow extends JFrame {
|
||||||
public BotWindow(){
|
public BotWindow(){
|
||||||
super(HandieBot.APPLICATION_NAME);
|
super(HandieBot.APPLICATION_NAME);
|
||||||
//Setup GUI
|
//Setup GUI
|
||||||
|
|
||||||
//Output area.
|
//Output area.
|
||||||
outputArea = new JTextPane();
|
outputArea = new JTextPane();
|
||||||
outputArea.setBackground(Color.white);
|
outputArea.setBackground(Color.white);
|
||||||
|
@ -30,6 +40,22 @@ public class BotWindow extends JFrame {
|
||||||
scrollPane.setViewportView(outputArea);
|
scrollPane.setViewportView(outputArea);
|
||||||
scrollPane.setAutoscrolls(true);
|
scrollPane.setAutoscrolls(true);
|
||||||
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
//Playlist shower
|
||||||
|
JPanel playlistSub = new JPanel(new BorderLayout());
|
||||||
|
JTextPane textPane = new JTextPane();
|
||||||
|
textPane.setEditable(false);
|
||||||
|
JScrollPane playlist = new JScrollPane(textPane);
|
||||||
|
playlist.setPreferredSize(new Dimension(250, 200));
|
||||||
|
playlistSub.add(playlist, BorderLayout.PAGE_END);
|
||||||
|
|
||||||
|
//PlaylistList maker
|
||||||
|
JList<String> list = setPlayListListArea(textPane);
|
||||||
|
JScrollPane playlistList = new JScrollPane(list);
|
||||||
|
playlistList.setPreferredSize(new Dimension(250, 1000));
|
||||||
|
playlistSub.add(playlistList, BorderLayout.CENTER);
|
||||||
|
getContentPane().add(playlistSub, BorderLayout.EAST);
|
||||||
|
|
||||||
//Command field.
|
//Command field.
|
||||||
JTextField commandField = new JTextField();
|
JTextField commandField = new JTextField();
|
||||||
commandField.setFont(new Font("Courier New", Font.PLAIN, 16));
|
commandField.setFont(new Font("Courier New", Font.PLAIN, 16));
|
||||||
|
@ -38,6 +64,7 @@ public class BotWindow extends JFrame {
|
||||||
|
|
||||||
//Standard JFrame setup code.
|
//Standard JFrame setup code.
|
||||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||||
|
|
||||||
//Add a listener to override the user attempting to close the program.
|
//Add a listener to override the user attempting to close the program.
|
||||||
addWindowListener(new WindowAdapter() {
|
addWindowListener(new WindowAdapter() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,12 +82,49 @@ public class BotWindow extends JFrame {
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
setJMenuBar(new MenuBar());
|
setJMenuBar(new MenuBar(this));
|
||||||
|
SelectionController controller = new SelectionController();
|
||||||
setPreferredSize(new Dimension(800, 600));
|
setPreferredSize(new Dimension(800, 600));
|
||||||
pack();
|
pack();
|
||||||
|
setLocationRelativeTo(null);
|
||||||
setVisible(true);
|
setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private JList<String> setPlayListListArea(JTextPane pane) {
|
||||||
|
List<String> playlistList = Playlist.getAvailablePlaylists();
|
||||||
|
String labels[] = new String[playlistList.size()];
|
||||||
|
int i=0;
|
||||||
|
for (String playlist : playlistList) {
|
||||||
|
labels[i] = playlist;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
JList<String> list = new JList<>(labels);
|
||||||
|
list.addListSelectionListener(e -> {
|
||||||
|
String name = list.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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
public JTextPane getOutputArea(){
|
public JTextPane getOutputArea(){
|
||||||
return this.outputArea;
|
return this.outputArea;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,8 +40,10 @@ public class CommandLineListener implements KeyListener {
|
||||||
* @param args The list of arguments for the command.
|
* @param args The list of arguments for the command.
|
||||||
*/
|
*/
|
||||||
private void executeCommand(String command, String[] args) {
|
private void executeCommand(String command, String[] args) {
|
||||||
if (command.equals("quit")){
|
switch (command) {
|
||||||
|
case "quit":
|
||||||
Commands.executeCommand("quit", null);
|
Commands.executeCommand("quit", null);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package handiebot.view;
|
package handiebot.view;
|
||||||
|
|
||||||
import handiebot.command.Commands;
|
import handiebot.command.Commands;
|
||||||
|
import handiebot.command.commands.interfaceActions.PlaylistAction;
|
||||||
import handiebot.view.actions.ActionItem;
|
import handiebot.view.actions.ActionItem;
|
||||||
import handiebot.view.actions.CommandAction;
|
import handiebot.view.actions.CommandAction;
|
||||||
|
|
||||||
|
@ -9,15 +10,23 @@ import javax.swing.*;
|
||||||
import static handiebot.HandieBot.resourceBundle;
|
import static handiebot.HandieBot.resourceBundle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Andrew Lalis
|
* @author Andrew Lalis & Zino Holwerda
|
||||||
* Custom menu bar to be added to the console control panel.
|
* Custom menu bar to be added to the console control panel.
|
||||||
*/
|
*/
|
||||||
public class MenuBar extends JMenuBar {
|
public class MenuBar extends JMenuBar {
|
||||||
|
|
||||||
public MenuBar(){
|
private BotWindow window;
|
||||||
JMenu fileMenu = new JMenu(resourceBundle.getString("menu.filemenu.title"));
|
private int language;
|
||||||
fileMenu.add(new ActionItem(resourceBundle.getString("menu.filemenu.quit"), new CommandAction(Commands.get("quit"))));
|
|
||||||
|
public MenuBar(BotWindow window){
|
||||||
|
this.window = window;
|
||||||
|
JMenu fileMenu = new JMenu(resourceBundle.getString("menu.fileMenu.title"));
|
||||||
|
fileMenu.add(new ActionItem(resourceBundle.getString("menu.fileMenu.quit"), new CommandAction(Commands.get("quit"))));
|
||||||
|
fileMenu.add(new PlaylistAction());
|
||||||
this.add(fileMenu);
|
this.add(fileMenu);
|
||||||
|
JMenu viewMenu = new JMenu(resourceBundle.getString("menu.viewMenu.view"));
|
||||||
|
JMenu language = new JMenu(resourceBundle.getString("menu.viewMenu.language"));
|
||||||
|
this.add(viewMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#Strings for HandieBot:
|
#author: Andrew Lalis & Zino Holwerda
|
||||||
# The following strings are organized in a way that it should be intuitive how it will be used.
|
#INFO Strings for HandieBot:
|
||||||
|
#INFO The following strings are organized in a way that it should be intuitive how it will be used.
|
||||||
|
#INFO Language: English
|
||||||
|
|
||||||
#Log
|
#Log
|
||||||
log.loggingIn=Logging client in...
|
log.loggingIn=Logging client in...
|
||||||
log.init=HandieBot initialized.
|
log.init=HandieBot initialized.
|
||||||
|
@ -11,8 +14,16 @@ log.newVoiceChannel=No voice channel found, creating a new one.
|
||||||
window.close.question=Are you sure you want to exit and shutdown the bot?
|
window.close.question=Are you sure you want to exit and shutdown the bot?
|
||||||
window.close.title=Confirm shutdown
|
window.close.title=Confirm shutdown
|
||||||
#MenuBar
|
#MenuBar
|
||||||
menu.filemenu.title=File
|
menu.fileMenu.title=File
|
||||||
menu.filemenu.quit=Quit
|
menu.fileMenu.quit=Quit
|
||||||
|
menu.editMenu.edit=Edit
|
||||||
|
menu.viewMenu.view=View
|
||||||
|
menu.viewMenu.language=Language
|
||||||
|
#Actions
|
||||||
|
action.menu.playlist=Edit playlists
|
||||||
|
action.menu.playlist.add=Add
|
||||||
|
action.menu.playlist.delete=Delete
|
||||||
|
action.menu.playlist.edit=Edit
|
||||||
#Generic Command Messages
|
#Generic Command Messages
|
||||||
commands.noPermission.message=You do not have permission to use the command `{0}`.
|
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.log=User {0} does not have permission to execute {1}
|
||||||
|
@ -24,7 +35,7 @@ commands.command.setPrefix.loadedPrefixes=Loaded prefixes.
|
||||||
commands.command.setPrefix.savedPrefixes=Saved prefixes.
|
commands.command.setPrefix.savedPrefixes=Saved prefixes.
|
||||||
commands.command.help.description=Displays a list of commands and what they do.
|
commands.command.help.description=Displays a list of commands and what they do.
|
||||||
commands.command.info.description=Displays some common commands and information about the bot.
|
commands.command.info.description=Displays some common commands and information about the bot.
|
||||||
commands.command.info.embed.description=HandieBot is a Discord bot created by Andrew Lalis. It can play music, manage playlists, and provide other assistance to users. Some useful commands are shown below.
|
commands.command.info.embed.description=HandieBot is a Discord bot created by Andrew Lalis & Zino Holwerda. It can play music, manage playlists, and provide other assistance to users. Some useful commands are shown below.
|
||||||
commands.command.info.embed.helpCommand=Receive a message with a detailed list of all commands and how to use them.
|
commands.command.info.embed.helpCommand=Receive a message with a detailed list of all commands and how to use them.
|
||||||
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.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.info.embed.queueCommand=Show a list of songs that will soon be played.
|
||||||
|
|
|
@ -1,22 +1,27 @@
|
||||||
#Strings for HandieBot:
|
#author: Zino Holwerda
|
||||||
# The following strings are organized in a way that it should be intuitive how it will be used.
|
#INFO Strings for HandieBot:
|
||||||
|
#INFO The following strings are organized in a way that it should be intuitive how it will be used.
|
||||||
|
#INFO Language: Dutch
|
||||||
|
|
||||||
#Log
|
#Log
|
||||||
log.loggingIn=Logging client in...
|
log.loggingIn=Bezig met inloggen van de client...
|
||||||
log.init=HandieBot initialized.
|
log.init=HandieBot geïnitialiseerd.
|
||||||
log.shuttingDown=Shutting down the bot.
|
log.shuttingDown=Bezig met het afsluiten van de bot.
|
||||||
log.deleteMessageError=Unable to delete message. Please ensure that the bot has MANAGE_MESSAGES enabled, especially for this channel.
|
log.deleteMessageError=Niet mogelijk het bericht te vewijderen. Zorg er alstublieft voor dat de bot MANAGE_MESSAGES aan heeft, met name in dit kanaal.
|
||||||
log.creatingChatChannel=No chat channel found, creating a new one.
|
log.creatingChatChannel=Geen chat gevonden. Bezig met het maken er van.
|
||||||
log.newVoiceChannel=No voice channel found, creating a new one.
|
log.newVoiceChannel=Geen voice kanaal gevonden, Bezig met het maken er van.
|
||||||
#Window
|
#Window
|
||||||
window.close.question=Are you sure you want to exit and shutdown the bot?
|
window.close.question=Weet je zeker dat je de bot wil afsluiten?
|
||||||
window.close.title=Confirm shutdown
|
window.close.title=Stopzetten Bevestigen.
|
||||||
#MenuBar
|
#MenuBar
|
||||||
menu.filemenu.title=File
|
menu.fileMenu.title=Bestand
|
||||||
menu.filemenu.quit=Quit
|
menu.fileMenu.quit=Verlaten
|
||||||
|
menu.fileMenu.edit=Bewerken
|
||||||
|
menu.fileMenu.view=Beeld
|
||||||
#Generic Command Messages
|
#Generic Command Messages
|
||||||
commands.noPermission.message=You do not have permission to use the command `{0}`.
|
commands.noPermission.message=U hebt niet de toestemming om dit commando uit te voeren.`{0}`.
|
||||||
commands.noPermission.log=User {0} does not have permission to execute {1}
|
commands.noPermission.log=Gebruiker {0} heeft niet de toestemming voor het uitvoeren van {1}
|
||||||
commands.noPermission.subcommand=You don't have permission to do that.
|
commands.noPermission.subcommand=U hebt niet de toestemming om dat te doen.
|
||||||
commands.invalidCommand.noContext=Invalid command issued: {0}
|
commands.invalidCommand.noContext=Invalid command issued: {0}
|
||||||
commands.invalidCommand.context=Invalid command: {0} issued by: {1}
|
commands.invalidCommand.context=Invalid command: {0} issued by: {1}
|
||||||
#Messages for specific commands.
|
#Messages for specific commands.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
{"installed":{"client_id":"901338445852-9e4l5o697fgj83q27gjaftonffdg2o9u.apps.googleusercontent.com","project_id":"pacific-nuance-172611","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"XQMJwz1gELEZAeu6hmEuFN1P","redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
|
Loading…
Reference in New Issue