diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..2b63946
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/com/shweit/poll/Poll.java b/src/main/java/com/shweit/poll/Poll.java
index 4a41e13..4a67157 100644
--- a/src/main/java/com/shweit/poll/Poll.java
+++ b/src/main/java/com/shweit/poll/Poll.java
@@ -1,6 +1,10 @@
package com.shweit.poll;
import com.shweit.poll.commands.CreatePollCommand;
+import com.shweit.poll.commands.pollDetailsCommand.PollDetailGuiListener;
+import com.shweit.poll.commands.pollsCommand.PollsCommand;
+import com.shweit.poll.commands.pollsCommand.PollsGuiListener;
+import com.shweit.poll.utils.ConnectionManager;
import com.shweit.poll.utils.Logger;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
@@ -10,7 +14,6 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
-import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
@@ -18,14 +21,19 @@ public final class Poll extends JavaPlugin {
public static Connection connection;
public static FileConfiguration config;
+ private static Poll instance;
@Override
public void onEnable() {
createConfig();
config = getConfig();
+ instance = this;
setupDatabase();
getCommand("createpoll").setExecutor(new CreatePollCommand());
+ getCommand("polls").setExecutor(new PollsCommand());
+ getServer().getPluginManager().registerEvents(new PollsGuiListener(), this);
+ getServer().getPluginManager().registerEvents(new PollDetailGuiListener(), this);
}
@Override
@@ -36,33 +44,34 @@ public void onDisable() {
}
} catch (SQLException e) {
Logger.error(e.toString());
+ e.printStackTrace();
}
}
+ public static Poll getInstance() {
+ return instance;
+ }
+
private void setupDatabase() {
- // Überprüfen, ob die Datei polls.sqlite existiert
File dbFile = new File(getDataFolder(), "polls.sqlite");
if (!dbFile.exists()) {
- // Wenn sie nicht existiert, erstelle sie
try {
if (!getDataFolder().exists()) {
getDataFolder().mkdirs();
}
- connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getPath());
- Logger.debug("Connected to new polls.sqlite database.");
+ Connection connection = new ConnectionManager().getConnection();
- // Lade und führe das SQL-Skript aus
- executeSqlScript(connection, "schema.sql");
+ executeSqlScript(connection, "sql/polls_table.sql");
+ executeSqlScript(connection, "sql/votes_table.sql");
} catch (SQLException e) {
e.printStackTrace();
}
} else {
- // Wenn die Datei existiert, verbinde mit der Datenbank
try {
- connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getPath());
+ Connection connection = new ConnectionManager().getConnection();
Logger.debug("Connected to existing polls.sqlite database.");
} catch (SQLException e) {
Logger.error(e.toString());
@@ -72,7 +81,6 @@ private void setupDatabase() {
private void executeSqlScript(Connection connection, String fileName) {
try {
- // Lade die SQL-Datei aus dem Ressourcen-Ordner
InputStream is = getResource(fileName);
if (is == null) {
Logger.error("SQL file not found: " + fileName);
diff --git a/src/main/java/com/shweit/poll/commands/CreatePollCommand.java b/src/main/java/com/shweit/poll/commands/CreatePollCommand.java
index 7a0c44d..23b2c3d 100644
--- a/src/main/java/com/shweit/poll/commands/CreatePollCommand.java
+++ b/src/main/java/com/shweit/poll/commands/CreatePollCommand.java
@@ -1,13 +1,13 @@
package com.shweit.poll.commands;
import com.shweit.poll.Poll;
-import com.shweit.poll.utils.Logger;
-import org.bukkit.ChatColor;
+import com.shweit.poll.utils.ConnectionManager;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.TabExecutor;
import org.bukkit.entity.Player;
+import com.google.gson.Gson;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -16,17 +16,16 @@
import java.util.List;
import java.util.UUID;
-public class CreatePollCommand implements CommandExecutor, TabExecutor
-{
+public class CreatePollCommand implements CommandExecutor, TabExecutor {
+ private final Gson gson = new Gson();
+
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
- if (!(sender instanceof Player)) {
+ if (!(sender instanceof Player player)) {
sender.sendMessage("This command can only be used by players.");
return true;
}
- Player player = (Player) sender;
-
if (args.length < 3) {
player.sendMessage("Usage: /createpoll \"\" \"\" \"\" ... [--multi]");
return false;
@@ -90,18 +89,19 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
}
private String convertListToJson(List list) {
- return "[" + String.join(",", list) + "]";
+ return gson.toJson(list);
}
- private void savePollToDatabase(UUID uniqueId, String string, String answersAsJsonString, boolean multi) throws SQLException {
- Connection connection = Poll.connection;
- String insertPollQuery = "INSERT INTO polls (uuid, question, answers, allowMultiple) VALUES (?, ?, ?, ?)";
+ private void savePollToDatabase(UUID uniqueId, String question, String answersAsJsonString, boolean multi) throws SQLException {
+ Connection connection = new ConnectionManager().getConnection();
+ String insertPollQuery = "INSERT INTO polls (uuid, question, answers, allowMultiple, isOpen) VALUES (?, ?, ?, ?, ?)";
try (PreparedStatement preparedStatement = connection.prepareStatement(insertPollQuery)) {
preparedStatement.setString(1, uniqueId.toString());
- preparedStatement.setString(2, string);
+ preparedStatement.setString(2, question);
preparedStatement.setString(3, answersAsJsonString);
preparedStatement.setBoolean(4, multi);
+ preparedStatement.setBoolean(5, true);
preparedStatement.executeUpdate();
}
}
diff --git a/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetailGuiListener.java b/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetailGuiListener.java
new file mode 100644
index 0000000..5e60844
--- /dev/null
+++ b/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetailGuiListener.java
@@ -0,0 +1,306 @@
+package com.shweit.poll.commands.pollDetailsCommand;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.shweit.poll.utils.ConnectionManager;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.Listener;
+import org.bukkit.event.inventory.InventoryClickEvent;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+public class PollDetailGuiListener implements Listener {
+ private final Gson gson = new Gson();
+
+ /**
+ * Handles the click event in the Poll Details inventory.
+ *
+ * @param event The InventoryClickEvent triggered when a player clicks inside the inventory.
+ */
+ @EventHandler
+ public void onInventoryClick(InventoryClickEvent event) {
+ Inventory inventory = event.getClickedInventory();
+
+ if (inventory == null || !event.getView().getTitle().equals(ChatColor.BLUE + "Poll Details")) {
+ return;
+ }
+
+ event.setCancelled(true);
+
+ ItemStack clickedItem = event.getCurrentItem();
+ if (clickedItem == null || !clickedItem.hasItemMeta()) {
+ return;
+ }
+
+ String displayName = clickedItem.getItemMeta().getDisplayName();
+ if (!displayName.startsWith(ChatColor.YELLOW.toString())) {
+ return;
+ }
+
+ String answer = ChatColor.stripColor(displayName);
+ Player player = (Player) event.getWhoClicked();
+ UUID playerUUID = player.getUniqueId();
+ int pollId = getPollIdFromInventory(inventory);
+
+ if (pollId == -1) {
+ player.sendMessage(ChatColor.RED + "Could not find the poll ID.");
+ return;
+ }
+
+ try (Connection connection = new ConnectionManager().getConnection()) {
+ if (hasVoted(playerUUID, pollId, connection)) {
+ if (isSelectedAnswer(playerUUID, pollId, answer, connection)) {
+ // Remove the answer if it is already selected
+ removeVote(playerUUID, pollId, answer, connection);
+ player.sendMessage(ChatColor.RED + "You deselected: " + answer);
+ } else if (allowsMultipleAnswers(pollId, connection)) {
+ // Add a new answer if multiple answers are allowed
+ addVote(playerUUID, pollId, answer, connection);
+ player.sendMessage(ChatColor.GREEN + "You selected: " + answer);
+ } else {
+ player.sendMessage(ChatColor.RED + "You have already voted. Multiple answers are not allowed.");
+ }
+ } else {
+ // Add the answer if no answer has been selected yet
+ addVote(playerUUID, pollId, answer, connection);
+ player.sendMessage(ChatColor.GREEN + "You selected: " + answer);
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ player.sendMessage(ChatColor.RED + "An error occurred while processing your vote.");
+ }
+
+ // Reopen the poll details inventory to reflect the updated votes
+ new PollDetailsCommand().openPollDetails(player, pollId);
+ }
+
+ /**
+ * Retrieves the poll ID from the inventory based on the lore of the item in slot 13.
+ *
+ * @param inventory The inventory containing the poll details.
+ * @return The poll ID or -1 if not found.
+ */
+ private int getPollIdFromInventory(Inventory inventory) {
+ ItemStack item = inventory.getItem(13); // Get the item in slot 13
+
+ if (item != null && item.hasItemMeta() && item.getItemMeta().hasLore()) {
+ List lore = item.getItemMeta().getLore();
+
+ if (lore != null) {
+ for (String line : lore) {
+ if (line.startsWith(ChatColor.GRAY + "ID: ")) {
+ try {
+ return Integer.parseInt(ChatColor.stripColor(line).replace("ID: ", ""));
+ } catch (NumberFormatException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+ return -1; // Return -1 if no ID is found
+ }
+
+ /**
+ * Checks if the player has already voted in the poll.
+ *
+ * @param playerUUID The UUID of the player.
+ * @param pollId The ID of the poll.
+ * @param connection The database connection.
+ * @return True if the player has voted, false otherwise.
+ * @throws SQLException If an SQL error occurs.
+ */
+ private boolean hasVoted(UUID playerUUID, int pollId, Connection connection) throws SQLException {
+ String query = "SELECT answers FROM votes WHERE uuid = ? AND poll_id = ?";
+ try (PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setString(1, playerUUID.toString());
+ statement.setInt(2, pollId);
+ try (ResultSet resultSet = statement.executeQuery()) {
+ if (resultSet.next()) {
+ String votes = resultSet.getString("answers");
+ return votes != null && !votes.isEmpty();
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if a specific answer is selected by the player in the poll.
+ *
+ * @param playerUUID The UUID of the player.
+ * @param pollId The ID of the poll.
+ * @param answer The answer to check.
+ * @param connection The database connection.
+ * @return True if the answer is selected, false otherwise.
+ * @throws SQLException If an SQL error occurs.
+ */
+ private boolean isSelectedAnswer(UUID playerUUID, int pollId, String answer, Connection connection) throws SQLException {
+ String query = "SELECT answers FROM votes WHERE uuid = ? AND poll_id = ?";
+ try (PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setString(1, playerUUID.toString());
+ statement.setInt(2, pollId);
+ try (ResultSet resultSet = statement.executeQuery()) {
+ if (resultSet.next()) {
+ String votes = resultSet.getString("answers");
+ if (votes != null && !votes.isEmpty()) {
+ if (votes.startsWith("[")) {
+ // JSON array
+ List voteList = gson.fromJson(votes, new TypeToken>() {}.getType());
+ return voteList.contains(answer);
+ } else {
+ // Simple string answer
+ return votes.equals(answer);
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks if the poll allows multiple answers.
+ *
+ * @param pollId The ID of the poll.
+ * @param connection The database connection.
+ * @return True if multiple answers are allowed, false otherwise.
+ * @throws SQLException If an SQL error occurs.
+ */
+ private boolean allowsMultipleAnswers(int pollId, Connection connection) throws SQLException {
+ String query = "SELECT allowMultiple FROM polls WHERE id = ?";
+ try (PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setInt(1, pollId);
+ try (ResultSet resultSet = statement.executeQuery()) {
+ if (resultSet.next()) {
+ return resultSet.getBoolean("allowMultiple");
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Adds a vote for the player to the poll.
+ *
+ * @param playerUUID The UUID of the player.
+ * @param pollId The ID of the poll.
+ * @param answer The answer to add.
+ * @param connection The database connection.
+ * @throws SQLException If an SQL error occurs.
+ */
+ private void addVote(UUID playerUUID, int pollId, String answer, Connection connection) throws SQLException {
+ String existingVotes = getPlayerVoteJson(playerUUID, pollId, connection);
+ List votes;
+
+ if (existingVotes != null && !existingVotes.isEmpty()) {
+ votes = gson.fromJson(existingVotes, new TypeToken>() {}.getType());
+ } else {
+ votes = new ArrayList<>();
+ }
+
+ if (!votes.contains(answer)) {
+ votes.add(answer);
+ }
+
+ String updateQuery = "UPDATE votes SET answers = ?, created_at = CURRENT_TIMESTAMP WHERE poll_id = ? AND uuid = ?";
+ String insertQuery = "INSERT INTO votes (poll_id, uuid, answers, created_at) VALUES (?, ?, ?, CURRENT_TIMESTAMP)";
+
+ try (PreparedStatement updateStatement = connection.prepareStatement(updateQuery)) {
+ updateStatement.setString(1, gson.toJson(votes));
+ updateStatement.setInt(2, pollId);
+ updateStatement.setString(3, playerUUID.toString());
+
+ int rowsAffected = updateStatement.executeUpdate();
+ if (rowsAffected == 0) {
+ // If no row was updated, insert a new record
+ try (PreparedStatement insertStatement = connection.prepareStatement(insertQuery)) {
+ insertStatement.setInt(1, pollId);
+ insertStatement.setString(2, playerUUID.toString());
+ insertStatement.setString(3, gson.toJson(votes));
+ insertStatement.executeUpdate();
+ }
+ }
+ }
+ }
+
+ /**
+ * Removes a vote for the player from the poll.
+ *
+ * @param playerUUID The UUID of the player.
+ * @param pollId The ID of the poll.
+ * @param answer The answer to remove.
+ * @param connection The database connection.
+ * @throws SQLException If an SQL error occurs.
+ */
+ private void removeVote(UUID playerUUID, int pollId, String answer, Connection connection) throws SQLException {
+ String existingVotes = getPlayerVoteJson(playerUUID, pollId, connection);
+ if (existingVotes == null || existingVotes.isEmpty()) {
+ return;
+ }
+
+ List votes;
+ if (existingVotes.startsWith("[")) {
+ // JSON array
+ votes = gson.fromJson(existingVotes, new TypeToken>() {}.getType());
+ } else {
+ // Simple string answer
+ votes = new ArrayList<>();
+ votes.add(existingVotes);
+ }
+
+ votes.remove(answer);
+
+ String query;
+ if (votes.isEmpty()) {
+ query = "DELETE FROM votes WHERE poll_id = ? AND uuid = ?";
+ try (PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setInt(1, pollId);
+ statement.setString(2, playerUUID.toString());
+ statement.executeUpdate();
+ }
+ } else {
+ query = "UPDATE votes SET answers = ?, created_at = CURRENT_TIMESTAMP WHERE poll_id = ? AND uuid = ?";
+ try (PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setString(1, gson.toJson(votes));
+ statement.setInt(2, pollId);
+ statement.setString(3, playerUUID.toString());
+ statement.executeUpdate();
+ }
+ }
+ }
+
+ /**
+ * Retrieves the player's votes for a specific poll as a JSON string.
+ *
+ * @param playerUUID The UUID of the player.
+ * @param pollId The ID of the poll.
+ * @param connection The database connection.
+ * @return The votes as a JSON string, or null if none are found.
+ * @throws SQLException If an SQL error occurs.
+ */
+ private String getPlayerVoteJson(UUID playerUUID, int pollId, Connection connection) throws SQLException {
+ String query = "SELECT answers FROM votes WHERE uuid = ? AND poll_id = ?";
+ try (PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setString(1, playerUUID.toString());
+ statement.setInt(2, pollId);
+ try (ResultSet resultSet = statement.executeQuery()) {
+ if (resultSet.next()) {
+ return resultSet.getString("answers");
+ }
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetails.java b/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetails.java
new file mode 100644
index 0000000..b4f8c0c
--- /dev/null
+++ b/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetails.java
@@ -0,0 +1,46 @@
+package com.shweit.poll.commands.pollDetailsCommand;
+
+import java.util.List;
+
+public class PollDetails {
+
+ private final int pollId;
+ private final String question;
+ private final List answers;
+ private final String creator;
+ private final String createdAt;
+ private final boolean multi;
+
+ public PollDetails(int pollId, String question, List answers, String creator, String createdAt, boolean multi) {
+ this.pollId = pollId;
+ this.question = question;
+ this.answers = answers;
+ this.creator = creator;
+ this.createdAt = createdAt;
+ this.multi = multi;
+ }
+
+ public int getPollId() {
+ return pollId;
+ }
+
+ public String getQuestion() {
+ return question;
+ }
+
+ public List getAnswers() {
+ return answers;
+ }
+
+ public String getCreator() {
+ return creator;
+ }
+
+ public String getCreatedAt() {
+ return createdAt;
+ }
+
+ public boolean isMulti() {
+ return multi;
+ }
+}
diff --git a/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetailsCommand.java b/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetailsCommand.java
new file mode 100644
index 0000000..b2e63e4
--- /dev/null
+++ b/src/main/java/com/shweit/poll/commands/pollDetailsCommand/PollDetailsCommand.java
@@ -0,0 +1,217 @@
+package com.shweit.poll.commands.pollDetailsCommand;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.shweit.poll.utils.ConnectionManager;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.Material;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+
+import java.lang.reflect.Type;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.*;
+
+public class PollDetailsCommand {
+
+ private final Gson gson = new Gson();
+
+ /**
+ * Opens a detailed view of a poll in an inventory GUI for the player.
+ * @param player The player for whom the GUI is opened.
+ * @param pollId The ID of the poll to display.
+ */
+ public void openPollDetails(Player player, int pollId) {
+ Inventory pollDetailsInventory = Bukkit.createInventory(null, 54, ChatColor.BLUE + "Poll Details");
+
+ PollDetails pollDetails = getPollDetails(pollId);
+ List answers = pollDetails.getAnswers();
+ List playerVotes = getPlayerVotes(player.getUniqueId(), pollId);
+ Map voteCounts = getVoteCounts(pollId);
+
+ // Add a border around the inventory
+ ItemStack borderItem = new ItemStack(Material.LIGHT_GRAY_STAINED_GLASS_PANE);
+ ItemMeta borderMeta = borderItem.getItemMeta();
+ borderMeta.setDisplayName(" ");
+ borderItem.setItemMeta(borderMeta);
+
+ for (int i = 0; i < 54; i++) {
+ if (i < 10 || i > 43 || i % 9 == 0 || (i + 1) % 9 == 0) {
+ pollDetailsInventory.setItem(i, borderItem);
+ }
+ }
+
+ // Add the question at the top center
+ ItemStack questionItem = new ItemStack(Material.PAPER);
+ ItemMeta questionMeta = questionItem.getItemMeta();
+ questionMeta.setDisplayName(ChatColor.GOLD + pollDetails.getQuestion());
+
+ List questionLore = new ArrayList<>();
+ OfflinePlayer creator = Bukkit.getOfflinePlayer(UUID.fromString(pollDetails.getCreator()));
+ questionLore.add(ChatColor.GRAY + "Created by: " + ChatColor.GREEN + creator.getName());
+ questionLore.add(ChatColor.GRAY + "Created on: " + ChatColor.GREEN + pollDetails.getCreatedAt());
+ questionLore.add(ChatColor.GRAY + "ID: " + ChatColor.GREEN + pollDetails.getPollId());
+ questionLore.add("");
+ questionLore.add(ChatColor.GRAY + "Your vote: " + ChatColor.AQUA + (!playerVotes.isEmpty() ? String.join(", ", playerVotes) : "None"));
+ if (pollDetails.isMulti()) {
+ questionLore.add("");
+ questionLore.add(ChatColor.GREEN + "You can vote for multiple answers.");
+ }
+ questionMeta.setLore(questionLore);
+
+ questionItem.setItemMeta(questionMeta);
+ pollDetailsInventory.setItem(13, questionItem);
+
+ // Add the answers
+ int startSlot = 19; // First slot for answers
+ for (String answer : answers) {
+ Material material = playerVotes.contains(answer) ? Material.GREEN_TERRACOTTA : Material.RED_TERRACOTTA;
+ ItemStack answerItem = new ItemStack(material);
+ ItemMeta meta = answerItem.getItemMeta();
+ meta.setDisplayName(ChatColor.YELLOW + answer);
+
+ List lore = new ArrayList<>();
+ lore.add(ChatColor.GRAY + "Votes: " + ChatColor.AQUA + voteCounts.getOrDefault(answer, 0));
+ meta.setLore(lore);
+
+ answerItem.setItemMeta(meta);
+ pollDetailsInventory.setItem(startSlot++, answerItem);
+
+ if (startSlot == 26) {
+ startSlot = 28; // Skip the middle slot to the next row
+ }
+ }
+
+ player.openInventory(pollDetailsInventory);
+ }
+
+ /**
+ * Retrieves detailed information about a poll from the database.
+ * @param pollId The ID of the poll to retrieve.
+ * @return A PollDetails object containing the poll's details.
+ */
+ private PollDetails getPollDetails(int pollId) {
+ PollDetails pollDetails = null;
+ String query = "SELECT question, answers, uuid, created_at, allowMultiple FROM polls WHERE id = ?";
+
+ try (Connection connection = new ConnectionManager().getConnection();
+ PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setInt(1, pollId);
+ try (ResultSet resultSet = statement.executeQuery()) {
+ if (resultSet.next()) {
+ String question = resultSet.getString("question");
+ String answersJson = resultSet.getString("answers");
+ String creator = resultSet.getString("uuid");
+ String createdAt = resultSet.getString("created_at");
+ boolean multi = resultSet.getBoolean("allowMultiple");
+
+ List answers = decodeAnswers(answersJson);
+ pollDetails = new PollDetails(pollId, question, answers, creator, createdAt, multi);
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return pollDetails;
+ }
+
+ /**
+ * Retrieves the votes of a player for a specific poll.
+ * @param playerUUID The UUID of the player.
+ * @param pollId The ID of the poll.
+ * @return A list of answers the player voted for.
+ */
+ private List getPlayerVotes(UUID playerUUID, int pollId) {
+ try (Connection connection = new ConnectionManager().getConnection()) {
+ String votesJson = getPlayerVoteJson(playerUUID, pollId, connection);
+ if (votesJson != null && !votesJson.isEmpty()) {
+ if (votesJson.startsWith("[")) {
+ // The votes are stored as a JSON array
+ return gson.fromJson(votesJson, new TypeToken>() {}.getType());
+ } else {
+ // The votes are stored as a simple string
+ List singleVoteList = new ArrayList<>();
+ singleVoteList.add(votesJson);
+ return singleVoteList;
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return new ArrayList<>();
+ }
+
+ /**
+ * Retrieves the votes of a player for a specific poll as a JSON string.
+ * @param playerUUID The UUID of the player.
+ * @param pollId The ID of the poll.
+ * @param connection The database connection.
+ * @return The votes as a JSON string.
+ * @throws SQLException If an SQL error occurs.
+ */
+ private String getPlayerVoteJson(UUID playerUUID, int pollId, Connection connection) throws SQLException {
+ String query = "SELECT answers FROM votes WHERE uuid = ? AND poll_id = ?";
+ try (PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setString(1, playerUUID.toString());
+ statement.setInt(2, pollId);
+ try (ResultSet resultSet = statement.executeQuery()) {
+ if (resultSet.next()) {
+ return resultSet.getString("answers");
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Retrieves the vote counts for each answer in a poll.
+ * @param pollId The ID of the poll.
+ * @return A map of answers to their corresponding vote counts.
+ */
+ private Map getVoteCounts(int pollId) {
+ Map voteCounts = new HashMap<>();
+ String query = "SELECT answers FROM votes WHERE poll_id = ?";
+
+ try (Connection connection = new ConnectionManager().getConnection();
+ PreparedStatement statement = connection.prepareStatement(query)) {
+ statement.setInt(1, pollId);
+ try (ResultSet resultSet = statement.executeQuery()) {
+ while (resultSet.next()) {
+ String answers = resultSet.getString("answers");
+ if (answers != null && !answers.isEmpty()) {
+ if (answers.startsWith("[")) {
+ List answerList = gson.fromJson(answers, new TypeToken>() {}.getType());
+ for (String answer : answerList) {
+ voteCounts.put(answer, voteCounts.getOrDefault(answer, 0) + 1);
+ }
+ } else {
+ voteCounts.put(answers, voteCounts.getOrDefault(answers, 0) + 1);
+ }
+ }
+ }
+ }
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+
+ return voteCounts;
+ }
+
+ /**
+ * Decodes a JSON string of answers into a list.
+ * @param answersJson The JSON string of answers.
+ * @return A list of answers.
+ */
+ private List decodeAnswers(String answersJson) {
+ Type listType = new TypeToken>() {}.getType();
+ return gson.fromJson(answersJson, listType);
+ }
+}
diff --git a/src/main/java/com/shweit/poll/commands/pollsCommand/PollsCommand.java b/src/main/java/com/shweit/poll/commands/pollsCommand/PollsCommand.java
new file mode 100644
index 0000000..db73f03
--- /dev/null
+++ b/src/main/java/com/shweit/poll/commands/pollsCommand/PollsCommand.java
@@ -0,0 +1,147 @@
+package com.shweit.poll.commands.pollsCommand;
+
+import com.shweit.poll.utils.ConnectionManager;
+import org.bukkit.Bukkit;
+import org.bukkit.ChatColor;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandExecutor;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.inventory.Inventory;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.bukkit.Material;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.*;
+
+public class PollsCommand implements CommandExecutor {
+
+ @Override
+ public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
+ if (!(sender instanceof Player)) {
+ sender.sendMessage("This command can only be used by players.");
+ return true;
+ }
+
+ Player player = (Player) sender;
+ int page = 0;
+
+ if (args.length > 0) {
+ try {
+ page = Integer.parseInt(args[0]) - 1;
+ } catch (NumberFormatException e) {
+ player.sendMessage(ChatColor.RED + "Invalid page number.");
+ return false;
+ }
+ }
+
+ openPollsGUI(player, page);
+
+ return true;
+ }
+
+ /**
+ * Opens the Polls GUI for the player, displaying a paginated list of open polls.
+ *
+ * @param player The player to whom the GUI is shown.
+ * @param page The page number to display.
+ */
+ private void openPollsGUI(Player player, int page) {
+ List