0

Initial commit of Redstoner-Bot.

This commit is contained in:
Logan Fick
2019-03-10 18:28:57 -04:00
commit 3c88f2e9f2
25 changed files with 1350 additions and 0 deletions

147
.gitignore vendored Normal file
View File

@@ -0,0 +1,147 @@
# Created by https://www.gitignore.io/api/java,linux,gradle,intellij,redis
# Edit at https://www.gitignore.io/?templates=java,linux,gradle,intellij,redis
### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr
# Sonarlint plugin
.idea/sonarlint
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### Redis ###
# Ignore redis binary dump (dump.rdb) files
*.rdb
### Gradle ###
.gradle
/build/
# Ignore Gradle GUI config
gradle-app.setting
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
# Cache of project
.gradletasknamecache
# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898
# gradle/wrapper/gradle-wrapper.properties
### Gradle Patch ###
**/build/
# End of https://www.gitignore.io/api/java,linux,gradle,intellij,redis

72
.idea/codeStyles/Project.xml generated Normal file
View File

@@ -0,0 +1,72 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<option name="LINE_SEPARATOR" value="&#10;" />
<option name="RIGHT_MARGIN" value="160" />
<option name="FORMATTER_TAGS_ENABLED" value="true" />
<option name="SOFT_MARGINS" value="120,160" />
<JavaCodeStyleSettings>
<option name="ALIGN_MULTILINE_ANNOTATION_PARAMETERS" value="true" />
<option name="JD_ADD_BLANK_AFTER_PARM_COMMENTS" value="true" />
<option name="JD_ADD_BLANK_AFTER_RETURN" value="true" />
<option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true" />
</JavaCodeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="ALIGN_MULTILINE_CHAINED_METHODS" value="true" />
<option name="ALIGN_MULTILINE_PARAMETERS_IN_CALLS" value="true" />
<option name="ALIGN_MULTILINE_BINARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_ASSIGNMENT" value="true" />
<option name="ALIGN_MULTILINE_TERNARY_OPERATION" value="true" />
<option name="ALIGN_MULTILINE_THROWS_LIST" value="true" />
<option name="ALIGN_MULTILINE_PARENTHESIZED_EXPRESSION" value="true" />
<option name="ALIGN_MULTILINE_ARRAY_INITIALIZER_EXPRESSION" value="true" />
<option name="ALIGN_GROUP_FIELD_DECLARATIONS" value="true" />
<option name="ALIGN_CONSECUTIVE_VARIABLE_DECLARATIONS" value="true" />
<option name="ALIGN_SUBSEQUENT_SIMPLE_METHODS" value="true" />
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true" />
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true" />
<option name="CALL_PARAMETERS_WRAP" value="1" />
<option name="CALL_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
<option name="CALL_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
<option name="METHOD_PARAMETERS_WRAP" value="1" />
<option name="RESOURCE_LIST_WRAP" value="5" />
<option name="THROWS_LIST_WRAP" value="1" />
<option name="EXTENDS_KEYWORD_WRAP" value="1" />
<option name="THROWS_KEYWORD_WRAP" value="1" />
<option name="METHOD_CALL_CHAIN_WRAP" value="5" />
<option name="WRAP_FIRST_METHOD_IN_CALL_CHAIN" value="true" />
<option name="TERNARY_OPERATION_WRAP" value="5" />
<option name="TERNARY_OPERATION_SIGNS_ON_NEXT_LINE" value="true" />
<option name="KEEP_SIMPLE_BLOCKS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_METHODS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_LAMBDAS_IN_ONE_LINE" value="true" />
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true" />
<option name="KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE" value="true" />
<option name="FOR_STATEMENT_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_WRAP" value="5" />
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true" />
<option name="ARRAY_INITIALIZER_RBRACE_ON_NEXT_LINE" value="true" />
<option name="ASSERT_STATEMENT_WRAP" value="1" />
<option name="ASSERT_STATEMENT_COLON_ON_NEXT_LINE" value="true" />
<option name="DOWHILE_BRACE_FORCE" value="1" />
<option name="FOR_BRACE_FORCE" value="1" />
<option name="SPACE_BEFORE_ANOTATION_PARAMETER_LIST" value="true" />
<option name="ENUM_CONSTANTS_WRAP" value="5" />
<indentOptions>
<option name="USE_TAB_CHARACTER" value="true" />
<option name="SMART_TABS" value="true" />
</indentOptions>
<arrangement>
<groups>
<group>
<type>GETTERS_AND_SETTERS</type>
<order>KEEP</order>
</group>
<group>
<type>DEPENDENT_METHODS</type>
<order>BREADTH_FIRST</order>
</group>
</groups>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

5
.idea/codeStyles/codeStyleConfig.xml generated Normal file
View File

@@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

9
.idea/compiler.xml generated Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel>
<module name="Redstoner-Bot.main" target="1.8" />
<module name="Redstoner-Bot.test" target="1.8" />
</bytecodeTargetLevel>
</component>
</project>

4
.idea/encodings.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>

26
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectInspectionProfilesVisibleTreeState">
<entry key="Project Default">
<profile-state>
<expanded-state>
<State />
<State>
<id>Manifest</id>
</State>
<State>
<id>Spelling</id>
</State>
</expanded-state>
<selected-state>
<State>
<id>SpellCheckingInspection</id>
</State>
</selected-state>
</profile-state>
</entry>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/classes" />
</component>
</project>

10
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/Redstoner-Bot.iml" filepath="$PROJECT_DIR$/Redstoner-Bot.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Redstoner-Bot.main.iml" filepath="$PROJECT_DIR$/.idea/modules/Redstoner-Bot.main.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/Redstoner-Bot.test.iml" filepath="$PROJECT_DIR$/.idea/modules/Redstoner-Bot.test.iml" />
</modules>
</component>
</project>

44
.idea/modules/Redstoner-Bot.main.iml generated Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="Redstoner-Bot:main" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="" external.system.module.type="sourceSet" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/../../out/production/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../src/main">
<sourceFolder url="file://$MODULE_DIR$/../../src/main/java" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: com.github.LogalDeveloper:LogalBot:f4f13ddc45" level="project" />
<orderEntry type="library" name="Gradle: net.dv8tion:JDA:3.8.3_460" level="project" />
<orderEntry type="library" name="Gradle: mysql:mysql-connector-java:5.1.37" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:16.0.1" level="project" />
<orderEntry type="library" name="Gradle: com.sedmelluq:lavaplayer:1.3.11" level="project" />
<orderEntry type="library" name="Gradle: org.slf4j:slf4j-simple:1.7.26" level="project" />
<orderEntry type="library" name="Gradle: redis.clients:jedis:2.9.3" level="project" />
<orderEntry type="library" name="Gradle: com.sedmelluq:lava-common:1.1.0" level="project" />
<orderEntry type="library" name="Gradle: org.slf4j:slf4j-api:1.7.26" level="project" />
<orderEntry type="library" name="Gradle: com.neovisionaries:nv-websocket-client:2.5" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp:3.13.0" level="project" />
<orderEntry type="library" name="Gradle: club.minnced:opus-java:pom:1.0.4" level="project" />
<orderEntry type="library" name="Gradle: org.apache.commons:commons-collections4:4.1" level="project" />
<orderEntry type="library" name="Gradle: org.json:json:20160810" level="project" />
<orderEntry type="library" name="Gradle: net.sf.trove4j:trove4j:3.0.3" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:1.17.2" level="project" />
<orderEntry type="library" name="Gradle: club.minnced:opus-java-api:1.0.4" level="project" />
<orderEntry type="library" name="Gradle: club.minnced:opus-java-natives:1.0.4" level="project" />
<orderEntry type="library" name="Gradle: com.sedmelluq:lavaplayer-natives:1.3.12" level="project" />
<orderEntry type="library" name="Gradle: org.apache.httpcomponents:httpclient:4.5.6" level="project" />
<orderEntry type="library" name="Gradle: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Gradle: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
<orderEntry type="library" name="Gradle: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
<orderEntry type="library" name="Gradle: org.jsoup:jsoup:1.11.3" level="project" />
<orderEntry type="library" name="Gradle: net.iharder:base64:2.3.9" level="project" />
<orderEntry type="library" name="Gradle: org.apache.commons:commons-pool2:2.4.3" level="project" />
<orderEntry type="library" name="Gradle: net.java.dev.jna:jna:4.4.0" level="project" />
<orderEntry type="library" name="Gradle: org.apache.httpcomponents:httpcore:4.4.10" level="project" />
<orderEntry type="library" name="Gradle: commons-logging:commons-logging:1.2" level="project" />
<orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
<orderEntry type="library" name="Gradle: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
</component>
</module>

44
.idea/modules/Redstoner-Bot.test.iml generated Normal file
View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="Redstoner-Bot:test" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="" external.system.module.type="sourceSet" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output-test url="file://$MODULE_DIR$/../../out/test/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$/../../src/test" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="Redstoner-Bot.main" />
<orderEntry type="library" name="Gradle: com.github.LogalDeveloper:LogalBot:f4f13ddc45" level="project" />
<orderEntry type="library" name="Gradle: net.dv8tion:JDA:3.8.3_460" level="project" />
<orderEntry type="library" name="Gradle: mysql:mysql-connector-java:5.1.37" level="project" />
<orderEntry type="library" name="Gradle: com.google.code.findbugs:jsr305:3.0.2" level="project" />
<orderEntry type="library" name="Gradle: org.jetbrains:annotations:16.0.1" level="project" />
<orderEntry type="library" name="Gradle: com.sedmelluq:lavaplayer:1.3.11" level="project" />
<orderEntry type="library" name="Gradle: org.slf4j:slf4j-simple:1.7.26" level="project" />
<orderEntry type="library" name="Gradle: redis.clients:jedis:2.9.3" level="project" />
<orderEntry type="library" name="Gradle: com.sedmelluq:lava-common:1.1.0" level="project" />
<orderEntry type="library" name="Gradle: org.slf4j:slf4j-api:1.7.26" level="project" />
<orderEntry type="library" name="Gradle: com.neovisionaries:nv-websocket-client:2.5" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okhttp3:okhttp:3.13.0" level="project" />
<orderEntry type="library" name="Gradle: club.minnced:opus-java:pom:1.0.4" level="project" />
<orderEntry type="library" name="Gradle: org.apache.commons:commons-collections4:4.1" level="project" />
<orderEntry type="library" name="Gradle: org.json:json:20160810" level="project" />
<orderEntry type="library" name="Gradle: net.sf.trove4j:trove4j:3.0.3" level="project" />
<orderEntry type="library" name="Gradle: com.squareup.okio:okio:1.17.2" level="project" />
<orderEntry type="library" name="Gradle: club.minnced:opus-java-api:1.0.4" level="project" />
<orderEntry type="library" name="Gradle: club.minnced:opus-java-natives:1.0.4" level="project" />
<orderEntry type="library" name="Gradle: com.sedmelluq:lavaplayer-natives:1.3.12" level="project" />
<orderEntry type="library" name="Gradle: org.apache.httpcomponents:httpclient:4.5.6" level="project" />
<orderEntry type="library" name="Gradle: commons-io:commons-io:2.6" level="project" />
<orderEntry type="library" name="Gradle: com.fasterxml.jackson.core:jackson-databind:2.9.8" level="project" />
<orderEntry type="library" name="Gradle: com.fasterxml.jackson.core:jackson-core:2.9.8" level="project" />
<orderEntry type="library" name="Gradle: org.jsoup:jsoup:1.11.3" level="project" />
<orderEntry type="library" name="Gradle: net.iharder:base64:2.3.9" level="project" />
<orderEntry type="library" name="Gradle: org.apache.commons:commons-pool2:2.4.3" level="project" />
<orderEntry type="library" name="Gradle: net.java.dev.jna:jna:4.4.0" level="project" />
<orderEntry type="library" name="Gradle: org.apache.httpcomponents:httpcore:4.4.10" level="project" />
<orderEntry type="library" name="Gradle: commons-logging:commons-logging:1.2" level="project" />
<orderEntry type="library" name="Gradle: commons-codec:commons-codec:1.10" level="project" />
<orderEntry type="library" name="Gradle: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
</component>
<component name="TestModuleProperties" production-module="Redstoner-Bot.main" />
</module>

5
.travis.yml Normal file
View File

@@ -0,0 +1,5 @@
language: java
jdk:
- openjdk8
- oraclejdk8

116
LICENSE.txt Normal file
View File

@@ -0,0 +1,116 @@
CC0 1.0 Universal
Statement of Purpose
The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator and
subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").
Certain owners wish to permanently relinquish those rights to a Work for the
purpose of contributing to a commons of creative, cultural and scientific
works ("Commons") that the public can reliably and without fear of later
claims of infringement build upon, modify, incorporate in other works, reuse
and redistribute as freely as possible in any form whatsoever and for any
purposes, including without limitation commercial purposes. These owners may
contribute to the Commons to promote the ideal of a free culture and the
further production of creative, cultural and scientific works, or to gain
reputation or greater distribution for their Work in part through the use and
efforts of others.
For these and/or other purposes and motivations, and without any expectation
of additional consideration or compensation, the person associating CC0 with a
Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
and publicly distribute the Work under its terms, with knowledge of his or her
Copyright and Related Rights in the Work and the meaning and intended legal
effect of CC0 on those rights.
1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not limited
to, the following:
i. the right to reproduce, adapt, distribute, perform, display, communicate,
and translate a Work;
ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or likeness
depicted in a Work;
iv. rights protecting against unfair competition in regards to a Work,
subject to the limitations in paragraph 4(a), below;
v. rights protecting the extraction, dissemination, use and reuse of data in
a Work;
vi. database rights (such as those arising under Directive 96/9/EC of the
European Parliament and of the Council of 11 March 1996 on the legal
protection of databases, and under any national implementation thereof,
including any amended or successor version of such directive); and
vii. other similar, equivalent or corresponding rights throughout the world
based on applicable law or treaty, and any national implementations thereof.
2. Waiver. To the greatest extent permitted by, but not in contravention of,
applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
and Related Rights and associated claims and causes of action, whether now
known or unknown (including existing as well as future claims and causes of
action), in the Work (i) in all territories worldwide, (ii) for the maximum
duration provided by applicable law or treaty (including future time
extensions), (iii) in any current or future medium and for any number of
copies, and (iv) for any purpose whatsoever, including without limitation
commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
the Waiver for the benefit of each member of the public at large and to the
detriment of Affirmer's heirs and successors, fully intending that such Waiver
shall not be subject to revocation, rescission, cancellation, termination, or
any other legal or equitable action to disrupt the quiet enjoyment of the Work
by the public as contemplated by Affirmer's express Statement of Purpose.
3. Public License Fallback. Should any part of the Waiver for any reason be
judged legally invalid or ineffective under applicable law, then the Waiver
shall be preserved to the maximum extent permitted taking into account
Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
is so judged Affirmer hereby grants to each affected person a royalty-free,
non transferable, non sublicensable, non exclusive, irrevocable and
unconditional license to exercise Affirmer's Copyright and Related Rights in
the Work (i) in all territories worldwide, (ii) for the maximum duration
provided by applicable law or treaty (including future time extensions), (iii)
in any current or future medium and for any number of copies, and (iv) for any
purpose whatsoever, including without limitation commercial, advertising or
promotional purposes (the "License"). The License shall be deemed effective as
of the date CC0 was applied by Affirmer to the Work. Should any part of the
License for any reason be judged legally invalid or ineffective under
applicable law, such partial invalidity or ineffectiveness shall not
invalidate the remainder of the License, and in such case Affirmer hereby
affirms that he or she will not (i) exercise any of his or her remaining
Copyright and Related Rights in the Work or (ii) assert any associated claims
and causes of action with respect to the Work, in either case contrary to
Affirmer's express Statement of Purpose.
4. Limitations and Disclaimers.
a. No trademark or patent rights held by Affirmer are waived, abandoned,
surrendered, licensed or otherwise affected by this document.
b. Affirmer offers the Work as-is and makes no representations or warranties
of any kind concerning the Work, express, implied, statutory or otherwise,
including without limitation warranties of title, merchantability, fitness
for a particular purpose, non infringement, or the absence of latent or
other defects, accuracy, or the present or absence of errors, whether or not
discoverable, all to the greatest extent permissible under applicable law.
c. Affirmer disclaims responsibility for clearing rights of other persons
that may apply to the Work or any use thereof, including without limitation
any person's Copyright and Related Rights in the Work. Further, Affirmer
disclaims responsibility for obtaining any necessary consents, permissions
or other rights required for any use of the Work.
d. Affirmer understands and acknowledges that Creative Commons is not a
party to this document and has no duty or obligation with respect to this
CC0 or use of the Work.
For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>

13
Redstoner-Bot.iml Normal file
View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="Redstoner-Bot" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
<excludeFolder url="file://$MODULE_DIR$/out" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

32
build.gradle Normal file
View File

@@ -0,0 +1,32 @@
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.2'
}
}
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'java'
repositories {
jcenter()
maven {
url 'https://jitpack.io'
}
}
dependencies {
implementation 'net.dv8tion:JDA:3.8.3_460'
implementation 'com.github.LogalDeveloper:LogalBot:f4f13ddc45'
implementation 'mysql:mysql-connector-java:5.1.37'
}
jar {
manifest {
attributes "Main-Class": "com.redstoner.discordbot.Main"
}
}

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

172
gradlew vendored Executable file
View File

@@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

1
settings.gradle Normal file
View File

@@ -0,0 +1 @@
rootProject.name = 'Redstoner-Bot'

View File

@@ -0,0 +1,59 @@
package com.redstoner.discordbot;
import com.redstoner.discordbot.commands.LinkAccount;
import com.redstoner.discordbot.commands.LinkStatus;
import com.redstoner.discordbot.commands.Nickname;
import com.redstoner.discordbot.tasks.ForumNotificationTask;
import com.redstoner.discordbot.tasks.GuildRankSyncTask;
import com.redstoner.discordbot.utils.RankUtil;
import dev.logal.logalbot.LogalBot;
import dev.logal.logalbot.commands.CommandManager;
import dev.logal.logalbot.utils.Scheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.TimeUnit;
public final class Main {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] arguments) {
logger.info("Beginning startup of Redstoner-Bot...");
RankUtil.registerRank("visitor", "470250026925293568");
RankUtil.registerRank("member", "470233551284076555");
RankUtil.registerRank("builder", "470233521919885317");
RankUtil.registerRank("trusted", "470233420501352469");
RankUtil.registerRank("helper", "518547428690100227");
RankUtil.registerRank("trainingmod", "470233311541985320");
RankUtil.registerRank("mod", "470233311541985320");
RankUtil.registerRank("admin", "470233150514003969");
RankUtil.registerRank("+lead", "516775853976453140");
RankUtil.registerRank("+donor", "470237589052325888");
RankUtil.registerRank("+donorplus", "470258077648683008");
RankUtil.registerRank("+retired", "537816902584631301");
RankUtil.registerRank("+dev", "508329092110614529");
logger.info("Starting LogalBot...");
LogalBot.start(false);
logger.info("Unregistering unnecessary commands...");
CommandManager.unregisterCommand("help");
CommandManager.unregisterCommand("about");
logger.info("Registering Redstoner commands...");
CommandManager.registerCommand("linkaccount", new LinkAccount(), false);
CommandManager.registerCommandAlias("link", "linkaccount");
CommandManager.registerCommandAlias("lnk", "linkaccount");
CommandManager.registerCommand("nickname", new Nickname(), true);
CommandManager.registerCommandAlias("nick", "nickname");
CommandManager.registerCommand("linkstatus", new LinkStatus(), false);
CommandManager.registerCommandAlias("ls", "linkstatus");
logger.info("Starting tasks...");
Scheduler.scheduleAtFixedRate(new ForumNotificationTask(), 1, 1, TimeUnit.MINUTES);
Scheduler.scheduleAtFixedRate(new GuildRankSyncTask(), 1, 5, TimeUnit.MINUTES);
logger.info("Redstoner-Bot setup complete.");
}
}

View File

@@ -0,0 +1,93 @@
package com.redstoner.discordbot.commands;
import com.redstoner.discordbot.utils.RankUtil;
import dev.logal.logalbot.commands.Command;
import dev.logal.logalbot.commands.CommandResponse;
import dev.logal.logalbot.utils.DataManager;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.TextChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public final class LinkAccount implements Command {
private static final Logger logger = LoggerFactory.getLogger(LinkAccount.class);
private final String databaseUsername = System.getenv("MYSQL_USERNAME");
private final String databasePassword = System.getenv("MYSQL_PASSWORD");
private final String tokenDatabaseName = System.getenv("MYSQL_TOKEN_DATABASE_NAME");
@Override
public CommandResponse execute(String[] arguments, Member executor, TextChannel channel) {
if (DataManager.getUserValue(executor, "minecraftUUID") != null) {
return new CommandResponse("no_entry_sign", "Sorry " + executor.getAsMention() + ", but your account is already linked.").setDeletionDelay(
10, TimeUnit.SECONDS);
}
String token = arguments[0];
if (token.length() != 8 || !token.matches("[A-Za-z0-9]+")) {
return new CommandResponse("no_entry_sign", "Sorry " + executor.getAsMention() + ", but that doesn't appear to be a token.").setDeletionDelay(
10, TimeUnit.SECONDS);
}
UUID uuid;
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + tokenDatabaseName, databaseUsername, databasePassword);
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT uuid FROM discord WHERE token='" + token + "' AND used=0");
if (!results.next()) {
return new CommandResponse(
"no_entry_sign", "Sorry " + executor.getAsMention() + ", but that token doesn't appear to be valid.").setDeletionDelay(
10, TimeUnit.SECONDS);
}
uuid = UUID.fromString(UUID
.fromString(results
.getString(1)
.replaceFirst(
"(\\p{XDigit}{8})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}{4})(\\p{XDigit}+)",
"$1-$2-$3-$4-$5"
))
.toString());
statement = connection.createStatement();
statement.execute("UPDATE discord SET used=1 WHERE token='" + token + "'");
connection.close();
} catch (Throwable exception) {
logger.error(
"An error occurred while trying to look up the token for " + executor.getEffectiveName() + " (" + executor.getUser().getId() + ")!",
exception
);
return new CommandResponse(
"sos", "Sorry " + executor.getAsMention() + ", but an error occurred while trying to look up your token.").setDeletionDelay(
10, TimeUnit.SECONDS);
}
DataManager.setUserValue(executor, "minecraftUUID", uuid.toString());
try {
RankUtil.syncRanks(executor);
} catch (Throwable exception) {
logger.error(
"An error occurred while trying to sync the ranks for " + executor.getEffectiveName() + " (" + executor.getUser().getId() + ")!",
exception
);
return new CommandResponse(
"exclamation",
executor.getAsMention() + ", your account has been successfully linked, but your ranks could not be synchronized at this time."
).setDeletionDelay(10, TimeUnit.SECONDS);
}
return new CommandResponse("link", executor.getAsMention() + ", your account has been successfully linked and your ranks have been synchronized.");
}
}

View File

@@ -0,0 +1,18 @@
package com.redstoner.discordbot.commands;
import dev.logal.logalbot.commands.Command;
import dev.logal.logalbot.commands.CommandResponse;
import dev.logal.logalbot.utils.DataManager;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.TextChannel;
public final class LinkStatus implements Command {
@Override
public CommandResponse execute(String[] arguments, Member executor, TextChannel channel) {
if (DataManager.getUserValue(executor, "minecraftUUID") == null) {
return new CommandResponse("negative_squared_cross_mark", executor.getAsMention() + ", your account is not linked.");
} else {
return new CommandResponse("ballot_box_with_check", executor.getAsMention() + ", your account is linked.");
}
}
}

View File

@@ -0,0 +1,96 @@
package com.redstoner.discordbot.commands;
import com.redstoner.discordbot.utils.RankUtil;
import dev.logal.logalbot.commands.Command;
import dev.logal.logalbot.commands.CommandResponse;
import dev.logal.logalbot.utils.DataManager;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.TextChannel;
import java.util.concurrent.TimeUnit;
public final class Nickname implements Command {
@Override
public CommandResponse execute(String[] arguments, Member executor, TextChannel channel) {
Guild guild = channel.getGuild();
if (arguments.length == 0) {
if (DataManager.getUserValue(executor, "minecraftUUID") == null) {
return new CommandResponse(
"no_entry_sign",
"Sorry " + executor.getAsMention() + ", but your nickname could not be reset because your account is not linked."
).setDeletionDelay(10, TimeUnit.SECONDS);
} else {
DataManager.setUserValue(executor, "nickname", "");
try {
RankUtil.syncRanks(executor);
return new CommandResponse("white_check_mark", executor.getAsMention() + ", your nickname has been reset.");
} catch (Throwable exception) {
return new CommandResponse(
"sos",
"Sorry " + executor.getAsMention() + ", but your nickname could not be reset because an error occurred while trying to look up your name."
).setDeletionDelay(10, TimeUnit.SECONDS);
}
}
}
String userID = arguments[0].replaceFirst("<@[!]?([0-9]*)>", "$1");
Member target;
try {
target = guild.getMemberById(userID);
} catch (Throwable exception) {
target = null;
}
if (target == null) {
if (DataManager.getUserValue(executor, "minecraftUUID") == null) {
return new CommandResponse(
"no_entry_sign",
"Sorry " + executor.getAsMention() + ", but your nickname could not be reset because your account is not linked."
).setDeletionDelay(10, TimeUnit.SECONDS);
} else {
DataManager.setUserValue(executor, "nickname", arguments[0]);
try {
RankUtil.syncRanks(executor);
return new CommandResponse("white_check_mark", executor.getAsMention() + ", your nickname has been set.");
} catch (Throwable exception) {
return new CommandResponse(
"sos",
"Sorry " + executor.getAsMention() + ", but your nickname could not be set because an error occurred while trying to look up your name."
).setDeletionDelay(10, TimeUnit.SECONDS);
}
}
} else {
if (DataManager.getUserValue(target, "minecraftUUID") == null) {
return new CommandResponse(
"no_entry_sign",
"Sorry " + executor.getAsMention() + ", but the nickname for that user could not be set because their account is not linked."
).setDeletionDelay(10, TimeUnit.SECONDS);
}
if (arguments.length == 1) {
try {
DataManager.setUserValue(target, "nickname", "");
RankUtil.syncRanks(target);
return new CommandResponse("white_check_mark", executor.getAsMention() + " has reset the nickname for " + target.getAsMention() + ".");
} catch (Throwable exception) {
return new CommandResponse(
"sos",
"Sorry " + executor.getAsMention() + ", but the nickname for that user could not be reset because an error occurred while trying to look up their name."
).setDeletionDelay(10, TimeUnit.SECONDS);
}
} else {
try {
DataManager.setUserValue(target, "nickname", arguments[1]);
RankUtil.syncRanks(target);
return new CommandResponse("white_check_mark", executor.getAsMention() + " has set the nickname for " + target.getAsMention() + ".");
} catch (Throwable exception) {
return new CommandResponse(
"sos",
"Sorry " + executor.getAsMention() + ", but the nickname for that user could not be set because an error occurred while trying to look up their name."
).setDeletionDelay(10, TimeUnit.SECONDS);
}
}
}
}
}

View File

@@ -0,0 +1,178 @@
package com.redstoner.discordbot.tasks;
import dev.logal.logalbot.LogalBot;
import dev.logal.logalbot.utils.DataManager;
import dev.logal.logalbot.utils.StringUtil;
import net.dv8tion.jda.core.entities.Guild;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.InputStream;
import java.net.URL;
public final class ForumNotificationTask implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(ForumNotificationTask.class);
private static final Guild redstonerGuild = LogalBot.getJDA().getGuildById("470229570310766593");
private static final String announcementsChannel = "489957437978181635";
private static final String staffGeneralChannel = "472452678367313941";
private static final String staffDevelopmentChannel = "491050574092042241";
@Override
public void run() {
try {
// Blog posts
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream stream = new URL("https://redstoner.com/blog.atom").openStream();
Document doc = docBuilder.parse(stream);
Element topEntry = (Element) doc.getDocumentElement().getElementsByTagName("entry").item(0);
String title = topEntry.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();
Element authorBlock = (Element) topEntry.getElementsByTagName("author").item(0);
String author = authorBlock.getElementsByTagName("name").item(0).getFirstChild().getNodeValue();
String id = topEntry.getElementsByTagName("id").item(0).getFirstChild().getNodeValue();
String link = topEntry.getElementsByTagName("link").item(0).getAttributes().getNamedItem("href").getNodeValue();
if (DataManager.getGuildValue(redstonerGuild, "knownAnnouncement:" + id) == null) {
LogalBot
.getJDA()
.getTextChannelById(announcementsChannel)
.sendMessage(
":loudspeaker: New blog post **" + StringUtil.sanitize(title) + "** authored by *" + StringUtil.sanitize(author) + "*\n" + link)
.queue();
DataManager.setGuildValue(redstonerGuild, "knownAnnouncement:" + id, "true");
}
} catch (Throwable exception) {
logger.error("An error occurred while posting new blog posts to Discord!", exception);
}
try {
// Blames
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream stream = new URL("https://redstoner.com/forums/21.atom").openStream();
Document doc = docBuilder.parse(stream);
Element topEntry = (Element) doc.getDocumentElement().getElementsByTagName("entry").item(0);
String title = topEntry.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();
Element authorBlock = (Element) topEntry.getElementsByTagName("author").item(0);
String author = authorBlock.getElementsByTagName("name").item(0).getFirstChild().getNodeValue();
String id = topEntry.getElementsByTagName("id").item(0).getFirstChild().getNodeValue();
String link = topEntry.getElementsByTagName("link").item(0).getAttributes().getNamedItem("href").getNodeValue();
if (DataManager.getGuildValue(redstonerGuild, "knownBlame:" + id) == null) {
LogalBot
.getJDA()
.getTextChannelById(staffGeneralChannel)
.sendMessage(
":loudspeaker: New blame **" + StringUtil.sanitize(title) + "** authored by *" + StringUtil.sanitize(author) + "*\n" + link)
.queue();
DataManager.setGuildValue(redstonerGuild, "knownBlame:" + id, "true");
}
} catch (Throwable exception) {
logger.error("An error occurred while posting new blames to Discord!", exception);
}
try {
// Appeals
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream stream = new URL("https://redstoner.com/forums/5.atom").openStream();
Document doc = docBuilder.parse(stream);
Element topEntry = (Element) doc.getDocumentElement().getElementsByTagName("entry").item(0);
String title = topEntry.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();
Element authorBlock = (Element) topEntry.getElementsByTagName("author").item(0);
String author = authorBlock.getElementsByTagName("name").item(0).getFirstChild().getNodeValue();
String id = topEntry.getElementsByTagName("id").item(0).getFirstChild().getNodeValue();
String link = topEntry.getElementsByTagName("link").item(0).getAttributes().getNamedItem("href").getNodeValue();
if (DataManager.getGuildValue(redstonerGuild, "knownAppeal:" + id) == null) {
LogalBot
.getJDA()
.getTextChannelById(staffGeneralChannel)
.sendMessage(
":loudspeaker: New appeal **" + StringUtil.sanitize(title) + "** authored by *" + StringUtil.sanitize(author) + "*\n" + link)
.queue();
DataManager.setGuildValue(redstonerGuild, "knownAppeal:" + id, "true");
}
} catch (Throwable exception) {
logger.error("An error occurred while posting new appeals to Discord!", exception);
}
try {
// Problems & Bugs
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream stream = new URL("https://redstoner.com/forums/11.atom").openStream();
Document doc = docBuilder.parse(stream);
Element topEntry = (Element) doc.getDocumentElement().getElementsByTagName("entry").item(0);
String title = topEntry.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();
Element authorBlock = (Element) topEntry.getElementsByTagName("author").item(0);
String author = authorBlock.getElementsByTagName("name").item(0).getFirstChild().getNodeValue();
String id = topEntry.getElementsByTagName("id").item(0).getFirstChild().getNodeValue();
String link = topEntry.getElementsByTagName("link").item(0).getAttributes().getNamedItem("href").getNodeValue();
if (DataManager.getGuildValue(redstonerGuild, "knownBugReport:" + id) == null) {
LogalBot
.getJDA()
.getTextChannelById(staffDevelopmentChannel)
.sendMessage(":loudspeaker: New bug report **" + StringUtil.sanitize(title) + "** authored by *" + StringUtil.sanitize(
author) + "*\n" + link)
.queue();
DataManager.setGuildValue(redstonerGuild, "knownBugReport:" + id, "true");
}
} catch (Throwable exception) {
logger.error("An error occurred while posting new bug reports to Discord!", exception);
}
try {
// Website Problems & Bugs
DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
InputStream stream = new URL("https://redstoner.com/forums/4.atom").openStream();
Document doc = docBuilder.parse(stream);
Element topEntry = (Element) doc.getDocumentElement().getElementsByTagName("entry").item(0);
String title = topEntry.getElementsByTagName("title").item(0).getFirstChild().getNodeValue();
Element authorBlock = (Element) topEntry.getElementsByTagName("author").item(0);
String author = authorBlock.getElementsByTagName("name").item(0).getFirstChild().getNodeValue();
String id = topEntry.getElementsByTagName("id").item(0).getFirstChild().getNodeValue();
String link = topEntry.getElementsByTagName("link").item(0).getAttributes().getNamedItem("href").getNodeValue();
if (DataManager.getGuildValue(redstonerGuild, "knownWebsiteBugReport:" + id) == null) {
LogalBot
.getJDA()
.getTextChannelById(staffDevelopmentChannel)
.sendMessage(":loudspeaker: New website bug report **" + StringUtil.sanitize(title) + "** authored by *" + StringUtil.sanitize(
author) + "*\n" + link)
.queue();
DataManager.setGuildValue(redstonerGuild, "knownWebsiteBugReport:" + id, "true");
}
} catch (Throwable exception) {
logger.error("An error occurred while posting new website bug reports to Discord!", exception);
}
}
}

View File

@@ -0,0 +1,30 @@
package com.redstoner.discordbot.tasks;
import com.redstoner.discordbot.utils.RankUtil;
import dev.logal.logalbot.LogalBot;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class GuildRankSyncTask implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(GuildRankSyncTask.class);
private static final String redstonerGuild = "470229570310766593";
@Override
public void run() {
Guild guild = LogalBot.getJDA().getGuildById(redstonerGuild);
for (Member member : guild.getMembers()) {
try {
RankUtil.syncRanks(member);
} catch (Throwable exception) {
logger.error(
"An error occurred while trying to sync the ranks for " + member.getUser().getName() + " (" + member.getUser().getId() + ")!",
exception
);
}
}
}
}

View File

@@ -0,0 +1,87 @@
package com.redstoner.discordbot.utils;
import dev.logal.logalbot.utils.DataManager;
import net.dv8tion.jda.core.entities.Guild;
import net.dv8tion.jda.core.entities.Member;
import net.dv8tion.jda.core.entities.Role;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
public final class RankUtil {
private static final Logger logger = LoggerFactory.getLogger(RankUtil.class);
private static final String databaseUsername = System.getenv("MYSQL_USERNAME");
private static final String databasePassword = System.getenv("MYSQL_PASSWORD");
private static final String pexDatabaseName = System.getenv("MYSQL_PEX_DATABASE_NAME");
private static final HashMap<String, String> roleDictionary = new HashMap<>();
public static void registerRank(String rankName, String roleID) {
roleDictionary.put(rankName, roleID);
}
public static void syncRanks(Member member) throws SQLException, ClassNotFoundException {
String uuid = DataManager.getUserValue(member, "minecraftUUID");
if (uuid == null) {
return;
}
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/" + pexDatabaseName, databaseUsername, databasePassword);
Statement statement = connection.createStatement();
ResultSet results = statement.executeQuery("SELECT parent FROM permissions_inheritance WHERE child='" + uuid + "'");
Guild guild = member.getGuild();
ArrayList<Role> rolesToAdd = new ArrayList<>();
while (results.next()) {
String parent = results.getString(1);
Role role = null;
if (roleDictionary.containsKey(parent)) {
role = guild.getRoleById(roleDictionary.get(parent));
}
if (role != null) {
rolesToAdd.add(role);
}
}
String nickname = DataManager.getUserValue(member, "nickname");
if (nickname != null && !nickname.equals("")) {
guild.getController().setNickname(member, nickname).reason("Redstoner Name Synchronization").queue();
} else {
statement = connection.createStatement();
results = statement.executeQuery("SELECT value FROM permissions WHERE type=1 AND permission='name' AND name='" + uuid + "'");
if (!results.next()) {
logger.warn(member.getUser().getName() + " (" + member
.getUser()
.getId() + ") has a linked account, but has no name according to PermissionsEx. Leaving Discord nickname as is.");
} else {
String name = results.getString(1);
if (!member.getEffectiveName().equals(name)) {
guild.getController().setNickname(member, name).reason("Redstoner Name Synchronization").queue();
}
}
}
connection.close();
if (rolesToAdd.size() == 0) {
logger.warn(member.getUser().getName() + " (" + member
.getUser()
.getId() + ") has a linked account, but has no ranks according to PermissionsEx. Assuming they are visitor rank.");
rolesToAdd.add(guild.getRoleById(roleDictionary.get("visitor")));
}
if (!CollectionUtils.isEqualCollection(member.getRoles(), rolesToAdd)) {
logger.info("Updating roles for " + member.getUser().getName() + " (" + member.getUser().getId() + ").");
guild.getController().modifyMemberRoles(member, rolesToAdd).reason("Redstoner Rank Synchronization").queue();
}
}
}