Compare commits
No commits in common. "master" and "bodgemaster" have entirely different histories.
master
...
bodgemaste
11
pom.xml
11
pom.xml
|
@ -12,17 +12,6 @@
|
||||||
<version>3.4.0</version>
|
<version>3.4.0</version>
|
||||||
<type>pom</type>
|
<type>pom</type>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.mariadb.jdbc/mariadb-java-client -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.mariadb.jdbc</groupId>
|
|
||||||
<artifactId>mariadb-java-client</artifactId>
|
|
||||||
<version>3.0.3</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.vdurmont</groupId>
|
|
||||||
<artifactId>emoji-java</artifactId>
|
|
||||||
<version>5.1.1</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
|
|
|
@ -4,55 +4,37 @@ import org.javacord.api.DiscordApi;
|
||||||
import org.javacord.api.DiscordApiBuilder;
|
import org.javacord.api.DiscordApiBuilder;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Scanner;
|
import java.util.Scanner;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static final String startupTime = String.format("%1$tY-%1$tm-%1$td %1$tI:%1$tM:%1$tS%1$tp UTC%1$tz", new Date());
|
|
||||||
private static String[] commandLineArguments;
|
|
||||||
private static long userID;
|
|
||||||
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
// [0] token, [1] db username, [2] db password
|
String startupTime = String.format("%1$tY-%1$tm-%1$td %1$tI:%1$tM:%1$tS%1$tp UTC%1$tz", new Date());
|
||||||
commandLineArguments = args;
|
|
||||||
|
|
||||||
// checks every 7500 ms if a deployment happened, if so shuts down the bot
|
// Insert your bot's token here
|
||||||
|
String token = args[0];
|
||||||
|
|
||||||
CheckDeploy check = new CheckDeploy(7500, "/var/www/deployment/Hacky-Quizbot/id.txt");
|
CheckDeploy check = new CheckDeploy(7500, "/var/www/deployment/Hacky-Quizbot/id.txt");
|
||||||
check.start();
|
check.start();
|
||||||
|
|
||||||
//TODO: remove, this is just a way of force loading of the QuizBackend class while it isn’t being loaded automatically
|
|
||||||
QuizBackend backend = new QuizBackend();
|
|
||||||
|
|
||||||
DiscordApi api = new DiscordApiBuilder().setToken(commandLineArguments[0]).login().join();
|
DiscordApi api = new DiscordApiBuilder().setToken(token).login().join();
|
||||||
userID = api.getYourself().getId();
|
|
||||||
System.err.println("Logging in as "+api.getYourself().getDiscriminatedName());
|
|
||||||
|
|
||||||
//user management
|
//Trivia management
|
||||||
ArrayList<QuizHandler> QuizHandlers = new ArrayList<QuizHandler>();
|
Member member = new Member(api);
|
||||||
|
|
||||||
// commands
|
// Add a listener which answers with "Pong!" if someone writes "!ping"
|
||||||
api.addMessageCreateListener(event -> {
|
api.addMessageCreateListener(event -> {
|
||||||
if (event.getMessageContent().equalsIgnoreCase("!ping")) {
|
if (event.getMessageContent().equalsIgnoreCase("!ping")) {
|
||||||
event.getChannel().sendMessage("Pong!\nHacky the quiz bot has been running since "+startupTime);
|
event.getChannel().sendMessage("Pong!\nHacky the quiz bot has been running since "+startupTime);
|
||||||
}
|
}
|
||||||
if (event.getMessageContent().equalsIgnoreCase("!trivia")) {
|
|
||||||
QuizHandlers.add(new QuizHandler(event.getMessageAuthor().asUser().get()));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
// Print the invite url of your bot
|
||||||
|
System.out.println("You can invite the bot by using the following url: " + api.createBotInvite());
|
||||||
public static String getCommandLineArgument(int index) {
|
|
||||||
return commandLineArguments[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getUserID() {
|
|
||||||
return userID;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Deploy check thread
|
|
||||||
public static class CheckDeploy extends Thread {
|
public static class CheckDeploy extends Thread {
|
||||||
private int interval;
|
private int interval;
|
||||||
private String id;
|
private String id;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package linux.general.hackyquizbot;
|
||||||
|
|
||||||
|
import org.javacord.api.DiscordApi;
|
||||||
|
import org.javacord.api.entity.user.User;
|
||||||
|
|
||||||
|
public class Member {
|
||||||
|
private DiscordApi api;
|
||||||
|
private User user;
|
||||||
|
|
||||||
|
public Member(DiscordApi api) {
|
||||||
|
this.api = api;
|
||||||
|
|
||||||
|
this.api.addMessageCreateListener(event ->{
|
||||||
|
if(event.getMessageContent().equalsIgnoreCase("!trivia")) {
|
||||||
|
if(event.getMessageAuthor().asUser().isPresent()) {
|
||||||
|
this.user = event.getMessageAuthor().asUser().get();
|
||||||
|
|
||||||
|
this.user.sendMessage("Welcome to hell");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,87 +1,69 @@
|
||||||
package linux.general.hackyquizbot;
|
package linux.general.hackyquizbot;
|
||||||
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.DriverManager;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.Statement;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class QuizBackend {
|
public class QuizBackend {
|
||||||
|
|
||||||
private static final String dbUsername = Main.getCommandLineArgument(1);
|
|
||||||
private static final String dbPassword = Main.getCommandLineArgument(2);
|
|
||||||
private static final String dbName = "jdbc:mariadb://localhost/quizbot"; //we can make this configurable later
|
|
||||||
private static Connection dbConnection;
|
|
||||||
private static Statement statement;
|
|
||||||
|
|
||||||
// temporary hack to get something working
|
|
||||||
private static boolean once = true;
|
|
||||||
|
|
||||||
// CREATE TABLE questions(id INT(32) AUTO_INCREMENT PRIMARY KEY, question TEXT, max_score INT(8));
|
|
||||||
// CREATE TABLE answer_choices(id INT(32), answer VARCHAR(2048), correctness BOOLEAN);
|
|
||||||
// CREATE TABLE user_answers(id INT(32), given_answer VARCHAR(2048), discord_user VARCHAR(1024));
|
|
||||||
// CREATE TABLE categories(id INT(32), category VARCHAR(1024));
|
|
||||||
|
|
||||||
private static Question[] allQuestions;
|
|
||||||
private static ArrayList<String> categories;
|
|
||||||
|
|
||||||
static {
|
|
||||||
|
|
||||||
categories = new ArrayList<String>();
|
|
||||||
try {
|
|
||||||
dbConnection = DriverManager.getConnection(dbName, dbUsername, dbPassword);
|
|
||||||
System.err.println("Database connected.");
|
|
||||||
statement = dbConnection.createStatement();
|
|
||||||
System.err.println("Statement object created.");
|
|
||||||
// populate categories
|
|
||||||
ResultSet resultSet = statement.executeQuery("SELECT category FROM categories;");
|
|
||||||
while (resultSet.next()) {
|
|
||||||
String category = resultSet.getString("category");
|
|
||||||
if (!categories.contains(category)) {
|
|
||||||
categories.add(category);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.err.print("Loaded categories:");
|
|
||||||
for (int i = 0; i<categories.size(); i++) {
|
|
||||||
System.err.print(" " + categories.get(i));
|
|
||||||
}
|
|
||||||
System.err.println();
|
|
||||||
//TODO: populate allQuestions
|
|
||||||
}
|
|
||||||
catch (SQLException e) {
|
|
||||||
System.err.println("Error while interacting with DB.");
|
|
||||||
e.printStackTrace();
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String[] getCategories() {
|
public static String[] getCategories() {
|
||||||
return (String[]) categories.toArray();
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Question getRandomQuestionForCategory(String category) {
|
||||||
//TODO: user aware random question picker
|
return null;
|
||||||
|
}
|
||||||
//TODO: function to determine whether a user should get more questions
|
|
||||||
public static boolean shouldGetMoreQuestions(String discordUserID) {
|
public static int getScoreForUser(String discordUserID) {
|
||||||
if (once) {
|
return 0;
|
||||||
once=false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: function to get a user’s score
|
|
||||||
|
|
||||||
public static class Question {
|
public static class Question {
|
||||||
|
|
||||||
//TODO: get full question text with multiple choice answers
|
/**
|
||||||
|
*
|
||||||
|
* @param question The string for the question text
|
||||||
|
* @param answers The multiple choice answers
|
||||||
|
* @param mask A mask to be layed over answers to decide which answers are correct and which aren’t
|
||||||
|
*/
|
||||||
|
public Question(String question, String[] answers, boolean[] mask) {
|
||||||
|
|
||||||
//TODO: get possible answers (scrambled per user)
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the full question text including multiple choice options with letters that correspond to getValidResponses()
|
||||||
|
*/
|
||||||
|
public String getQuestionTextWithOptions() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return a character array containing all the valid answers
|
||||||
|
*/
|
||||||
|
public char[] getValidResponses() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO: get correct answers (scrambled per user)
|
public char[] getCorrectResponses() {
|
||||||
|
return null;
|
||||||
//TODO: submit answer
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is used to send the user’s reply back to the backend. Can be called
|
||||||
|
* multiple times to add answers for questions with multiple possible answers.
|
||||||
|
*
|
||||||
|
* @param discordUserID
|
||||||
|
* @param answer
|
||||||
|
*/
|
||||||
|
public void addAnswer(String discordUserID, char answer) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to balance easy and difficult questions. Difficult questions will have a
|
||||||
|
* higher value so if someone gets a bunch of them they will get less questions
|
||||||
|
* overall.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public int getQuestionScoreValue() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
package linux.general.hackyquizbot;
|
|
||||||
|
|
||||||
import java.util.concurrent.ExecutionException;
|
|
||||||
|
|
||||||
import org.javacord.api.entity.message.Message;
|
|
||||||
import org.javacord.api.entity.user.User;
|
|
||||||
|
|
||||||
import com.vdurmont.emoji.EmojiParser;
|
|
||||||
|
|
||||||
import linux.general.hackyquizbot.QuizBackend.Question;
|
|
||||||
|
|
||||||
public class QuizHandler {
|
|
||||||
private User user;
|
|
||||||
private Question lastQuestion;
|
|
||||||
|
|
||||||
public QuizHandler(User user) {
|
|
||||||
this.user = user;
|
|
||||||
if (QuizBackend.shouldGetMoreQuestions(user.getIdAsString())) {
|
|
||||||
try {
|
|
||||||
Message message = user.sendMessage("Hi! I'm Hacky.\n"
|
|
||||||
+ "I will be sending you a bunch of multiple-choice questions. "
|
|
||||||
+ "You can answer by selecting one or more of the reactions on the message and confirm your selection by selecting the :white_check_mark: reaction."
|
|
||||||
+ " Please contact @BodgeMaster#0344 if there are any issues.\n\n"
|
|
||||||
+ "Select the :white_check_mark: reaction to continue.").get();
|
|
||||||
message.addReaction(EmojiParser.parseToUnicode(":white_check_mark:"));
|
|
||||||
message.addReactionAddListener(event -> {
|
|
||||||
// HACK: Testing for an exception to find out whether the event was caused by a
|
|
||||||
// user or by the bot itself because reactions added by the bot allow to check
|
|
||||||
// for user where reactions added by actual users don’t.
|
|
||||||
try {
|
|
||||||
if (!event.getUser().get().isYourself() && event.getReaction().get().getEmoji()
|
|
||||||
.equalsEmoji(EmojiParser.parseToUnicode(":white_check_mark:"))) {
|
|
||||||
event.getMessage().get().getChannel().sendMessage(
|
|
||||||
"This should not work. If you ever see this message, please inform @BodgeMaster#0344 that there is more to this arbitrary limitation in the Discord API than expected.");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println("Assuming the reaction event was caused by the user...");
|
|
||||||
System.err.println("User ID: "+this.user.getIdAsString()); //test if we can get the user ID that way
|
|
||||||
}
|
|
||||||
// TODO: trigger question dispatch
|
|
||||||
// TODO: remove ReactionAddListener
|
|
||||||
});
|
|
||||||
} catch (InterruptedException | ExecutionException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
System.err.println("Something went wrong while trying to get the sent message object.");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
// TODO: add white question mark reaction
|
|
||||||
|
|
||||||
// TODO: add reaction handler (preferably to channel?)
|
|
||||||
} else {
|
|
||||||
user.sendMessage(
|
|
||||||
"You have already had the maximum amount of questions that you can get with the current question set.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue