diff --git a/src/main/java/ca/tweetzy/auctionhouse/auction/AuctionAdminLog.java b/src/main/java/ca/tweetzy/auctionhouse/auction/AuctionAdminLog.java index 2da6288..d1a23db 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/auction/AuctionAdminLog.java +++ b/src/main/java/ca/tweetzy/auctionhouse/auction/AuctionAdminLog.java @@ -3,6 +3,7 @@ package ca.tweetzy.auctionhouse.auction; import ca.tweetzy.auctionhouse.auction.enums.AdminAction; import lombok.AllArgsConstructor; import lombok.Getter; +import org.bukkit.inventory.ItemStack; import java.util.UUID; @@ -16,12 +17,11 @@ import java.util.UUID; @Getter public final class AuctionAdminLog { - private final int id; private final UUID admin; private final String adminName; private final UUID target; private final String targetName; - private final String itemName; + private final ItemStack item; private final UUID itemId; private final AdminAction adminAction; private final long time; diff --git a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAdmin.java b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAdmin.java index 9762f82..43bc85c 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAdmin.java +++ b/src/main/java/ca/tweetzy/auctionhouse/commands/CommandAdmin.java @@ -3,6 +3,7 @@ package ca.tweetzy.auctionhouse.commands; import ca.tweetzy.auctionhouse.AuctionHouse; import ca.tweetzy.auctionhouse.api.AuctionAPI; import ca.tweetzy.auctionhouse.guis.GUISellItem; +import ca.tweetzy.auctionhouse.guis.admin.GUIAdminLogs; import ca.tweetzy.auctionhouse.helpers.PlayerHelper; import ca.tweetzy.auctionhouse.settings.Settings; import ca.tweetzy.core.commands.AbstractCommand; @@ -36,6 +37,17 @@ public class CommandAdmin extends AbstractCommand { if (AuctionAPI.tellMigrationStatus(sender)) return ReturnType.FAILURE; switch (args[0].toLowerCase()) { + case "logs": + if (!(sender instanceof Player)) break; + Player player = (Player) sender; + + AuctionHouse.getInstance().getDataManager().getAdminLogs((error, logs) -> { + if (error == null) + AuctionHouse.newChain().sync(() -> AuctionHouse.getInstance().getGuiManager().showGUI(player, new GUIAdminLogs(logs))).execute(); + else + error.printStackTrace(); + }); + break; case "endall": for (UUID id : AuctionHouse.getInstance().getAuctionItemManager().getItems().keySet()) { AuctionHouse.getInstance().getAuctionItemManager().getItems().get(id).setExpired(true); @@ -64,7 +76,7 @@ public class CommandAdmin extends AbstractCommand { break; case "opensell": if (args.length < 2) return ReturnType.FAILURE; - Player player = PlayerUtils.findPlayer(args[1]); + player = PlayerUtils.findPlayer(args[1]); if (player == null) return ReturnType.FAILURE; ItemStack itemToSell = PlayerHelper.getHeldItem(player).clone(); @@ -85,7 +97,7 @@ public class CommandAdmin extends AbstractCommand { @Override protected List onTab(CommandSender sender, String... args) { - if (args.length == 1) return Arrays.asList("endall", "relistall"); + if (args.length == 1) return Arrays.asList("endall", "relistall", "logs"); if (args.length == 2 && args[0].equalsIgnoreCase("relistAll")) return Arrays.asList("1", "2", "3", "4", "5"); return null; } diff --git a/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java b/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java index 5185408..c7d53ed 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java +++ b/src/main/java/ca/tweetzy/auctionhouse/database/DataManager.java @@ -3,15 +3,13 @@ package ca.tweetzy.auctionhouse.database; import ca.tweetzy.auctionhouse.AuctionHouse; import ca.tweetzy.auctionhouse.api.AuctionAPI; import ca.tweetzy.auctionhouse.auction.*; +import ca.tweetzy.auctionhouse.auction.enums.AdminAction; import ca.tweetzy.auctionhouse.auction.enums.AuctionItemCategory; import ca.tweetzy.auctionhouse.auction.enums.AuctionSaleType; -import ca.tweetzy.auctionhouse.settings.Settings; import ca.tweetzy.auctionhouse.transaction.Transaction; import ca.tweetzy.core.database.DataManagerAbstract; import ca.tweetzy.core.database.DatabaseConnector; import ca.tweetzy.core.database.MySQLConnector; -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -22,7 +20,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; -import java.util.stream.Collectors; /** * The current file has been created by Kiran Hart @@ -193,6 +190,22 @@ public class DataManager extends DataManagerAbstract { })); } + public void getAdminLogs(Callback> callback) { + ArrayList logs = new ArrayList<>(); + this.async(() -> this.databaseConnector.connect(connection -> { + try (PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + this.getTablePrefix() + "admin_logs")) { + ResultSet resultSet = statement.executeQuery(); + while (resultSet.next()) { + logs.add(extractAdminLog(resultSet)); + } + + callback.accept(null, logs); + } catch (Exception e) { + resolveCallback(callback, e); + } + })); + } + public void getTransactions(Callback> callback) { ArrayList transactions = new ArrayList<>(); this.async(() -> this.databaseConnector.connect(connection -> { @@ -239,6 +252,29 @@ public class DataManager extends DataManagerAbstract { }); } + public void insertLog(AuctionAdminLog adminLog) { + this.databaseConnector.connect(connection -> { + try (PreparedStatement statement = connection.prepareStatement("INSERT INTO " + this.getTablePrefix() + "admin_logs(admin, admin_name, target, target_name, item, item_id, action, time) VALUES(?, ?, ?, ?, ?, ?, ?, ?)")) { + + statement.setString(1, adminLog.getAdmin().toString()); + statement.setString(2, adminLog.getAdminName()); + statement.setString(3, adminLog.getTarget().toString()); + statement.setString(4, adminLog.getTargetName()); + statement.setString(5, AuctionAPI.encodeItem(adminLog.getItem())); + statement.setString(6, adminLog.getItemId().toString()); + statement.setString(7, adminLog.getAdminAction().name()); + statement.setLong(8, adminLog.getTime()); + statement.executeUpdate(); + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + + public void insertLogAsync(AuctionAdminLog adminLog) { + this.thread.execute(() -> insertLog(adminLog)); + } + public void insertTransactionAsync(Transaction transaction, Callback callback) { this.thread.execute(() -> insertTransaction(transaction, callback)); } @@ -432,6 +468,19 @@ public class DataManager extends DataManagerAbstract { ); } + private AuctionAdminLog extractAdminLog(ResultSet resultSet) throws SQLException { + return new AuctionAdminLog( + UUID.fromString(resultSet.getString("admin")), + resultSet.getString("admin_name"), + UUID.fromString(resultSet.getString("target")), + resultSet.getString("target_name"), + AuctionAPI.decodeItem(resultSet.getString("item")), + UUID.fromString(resultSet.getString("item_id")), + AdminAction.valueOf(resultSet.getString("action").toUpperCase()), + resultSet.getLong("time") + ); + } + private void resolveUpdateCallback(@Nullable UpdateCallback callback, @Nullable Exception ex) { if (callback != null) { callback.accept(ex); diff --git a/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_11_AdminLogMigration.java b/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_11_AdminLogMigration.java index 2424fc4..7f4aacc 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_11_AdminLogMigration.java +++ b/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_11_AdminLogMigration.java @@ -26,13 +26,13 @@ public final class _11_AdminLogMigration extends DataMigration { String autoIncrement = AuctionHouse.getInstance().getDatabaseConnector() instanceof MySQLConnector ? " AUTO_INCREMENT" : ""; - statement.execute("CREATE TABLE " + tablePrefix + "admin_logs (" + + statement.execute("CREATE TABLE IF NOT EXISTS " + tablePrefix + "admin_logs (" + "id INTEGER PRIMARY KEY" + autoIncrement + ", " + "admin VARCHAR(36) NOT NULL, " + "admin_name VARCHAR(16) NOT NULL, " + "target VARCHAR(36) NOT NULL, " + "target_name VARCHAR(16) NOT NULL, " + - "item_name TEXT NOT NULL, " + + "item TEXT NOT NULL, " + "item_id VARCHAR(36) NOT NULL, " + "action VARCHAR(36) NOT NULL, " + "time BigInt NOT NULL" + diff --git a/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_12_SerializeFormatDropMigration.java b/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_12_SerializeFormatDropMigration.java index 1168253..dc3165a 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_12_SerializeFormatDropMigration.java +++ b/src/main/java/ca/tweetzy/auctionhouse/database/migrations/_12_SerializeFormatDropMigration.java @@ -23,7 +23,7 @@ public class _12_SerializeFormatDropMigration extends DataMigration { @Override public void migrate(Connection connection, String tablePrefix) throws SQLException { try (Statement statement = connection.createStatement()) { - statement.execute("DROP TABLE " + tablePrefix + "items"); + statement.execute("DROP TABLE IF EXISTS " + tablePrefix + "items"); } } } diff --git a/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java b/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java index 54a8177..ce91ef9 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java +++ b/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAuctionHouse.java @@ -9,6 +9,7 @@ import ca.tweetzy.auctionhouse.auction.enums.AuctionItemCategory; import ca.tweetzy.auctionhouse.auction.enums.AuctionSaleType; import ca.tweetzy.auctionhouse.auction.enums.AuctionSortType; import ca.tweetzy.auctionhouse.auction.enums.AuctionStackType; +import ca.tweetzy.auctionhouse.guis.admin.GUIAdminItem; import ca.tweetzy.auctionhouse.guis.confirmation.GUIConfirmBid; import ca.tweetzy.auctionhouse.guis.confirmation.GUIConfirmPurchase; import ca.tweetzy.auctionhouse.guis.filter.GUIFilterSelection; diff --git a/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAdminItem.java b/src/main/java/ca/tweetzy/auctionhouse/guis/admin/GUIAdminItem.java similarity index 66% rename from src/main/java/ca/tweetzy/auctionhouse/guis/GUIAdminItem.java rename to src/main/java/ca/tweetzy/auctionhouse/guis/admin/GUIAdminItem.java index 6158d13..8b3e058 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/guis/GUIAdminItem.java +++ b/src/main/java/ca/tweetzy/auctionhouse/guis/admin/GUIAdminItem.java @@ -1,14 +1,21 @@ -package ca.tweetzy.auctionhouse.guis; +package ca.tweetzy.auctionhouse.guis.admin; import ca.tweetzy.auctionhouse.AuctionHouse; +import ca.tweetzy.auctionhouse.api.AuctionAPI; +import ca.tweetzy.auctionhouse.api.events.AuctionAdminEvent; +import ca.tweetzy.auctionhouse.auction.AuctionAdminLog; import ca.tweetzy.auctionhouse.auction.AuctionPlayer; import ca.tweetzy.auctionhouse.auction.AuctionedItem; +import ca.tweetzy.auctionhouse.auction.enums.AdminAction; +import ca.tweetzy.auctionhouse.guis.GUIAuctionHouse; import ca.tweetzy.auctionhouse.helpers.ConfigurationItemHelper; import ca.tweetzy.auctionhouse.settings.Settings; import ca.tweetzy.core.gui.Gui; import ca.tweetzy.core.utils.PlayerUtils; import ca.tweetzy.core.utils.TextUtils; +import org.bukkit.Bukkit; import org.bukkit.GameMode; +import org.bukkit.entity.Player; /** * The current file has been created by Kiran Hart @@ -36,18 +43,30 @@ public class GUIAdminItem extends Gui { private void draw() { setButton(1, 1, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_ITEM_ADMIN_ITEMS_RETURN_ITEM.getString(), Settings.GUI_ITEM_ADMIN_ITEMS_RETURN_NAME.getString(), Settings.GUI_ITEM_ADMIN_ITEMS_RETURN_LORE.getStringList(), null), e -> { + AuctionAdminEvent event = new AuctionAdminEvent(createLog(e.player, AdminAction.RETURN_ITEM)); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return; + this.auctionItem.setExpiresAt(System.currentTimeMillis()); this.auctionItem.setExpired(true); e.gui.close(); }); setButton(1, 3, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_ITEM_ADMIN_ITEMS_CLAIM_ITEM.getString(), Settings.GUI_ITEM_ADMIN_ITEMS_CLAIM_NAME.getString(), Settings.GUI_ITEM_ADMIN_ITEMS_CLAIM_LORE.getStringList(), null), e -> { + AuctionAdminEvent event = new AuctionAdminEvent(createLog(e.player, AdminAction.CLAIM_ITEM)); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return; + PlayerUtils.giveItem(e.player, this.auctionItem.getItem()); AuctionHouse.getInstance().getAuctionItemManager().sendToGarbage(this.auctionItem); e.gui.close(); }); setButton(1, 5, ConfigurationItemHelper.createConfigurationItem(Settings.GUI_ITEM_ADMIN_ITEMS_DELETE_ITEM.getString(), Settings.GUI_ITEM_ADMIN_ITEMS_DELETE_NAME.getString(), Settings.GUI_ITEM_ADMIN_ITEMS_DELETE_LORE.getStringList(), null), e -> { + AuctionAdminEvent event = new AuctionAdminEvent(createLog(e.player, AdminAction.DELETE_ITEM)); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return; + AuctionHouse.getInstance().getAuctionItemManager().sendToGarbage(this.auctionItem); e.gui.close(); }); @@ -58,8 +77,25 @@ public class GUIAdminItem extends Gui { return; } + AuctionAdminEvent event = new AuctionAdminEvent(createLog(e.player, AdminAction.COPY_ITEM)); + Bukkit.getServer().getPluginManager().callEvent(event); + if (event.isCancelled()) return; + PlayerUtils.giveItem(e.player, this.auctionItem.getItem()); e.gui.close(); }); } + + private AuctionAdminLog createLog(final Player player, AdminAction adminAction) { + return new AuctionAdminLog( + player.getUniqueId(), + player.getName(), + auctionItem.getOwner(), + auctionItem.getOwnerName(), + auctionItem.getItem(), + auctionItem.getId(), + adminAction, + System.currentTimeMillis() + ); + } } diff --git a/src/main/java/ca/tweetzy/auctionhouse/guis/admin/GUIAdminLogs.java b/src/main/java/ca/tweetzy/auctionhouse/guis/admin/GUIAdminLogs.java new file mode 100644 index 0000000..41a84ee --- /dev/null +++ b/src/main/java/ca/tweetzy/auctionhouse/guis/admin/GUIAdminLogs.java @@ -0,0 +1,59 @@ +package ca.tweetzy.auctionhouse.guis.admin; + +import ca.tweetzy.auctionhouse.api.AuctionAPI; +import ca.tweetzy.auctionhouse.auction.AuctionAdminLog; +import ca.tweetzy.auctionhouse.helpers.ConfigurationItemHelper; +import ca.tweetzy.auctionhouse.settings.Settings; +import ca.tweetzy.core.gui.Gui; +import ca.tweetzy.core.utils.TextUtils; +import ca.tweetzy.core.utils.items.TItemBuilder; + +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * The current file has been created by Kiran Hart + * Date Created: January 17 2022 + * Time Created: 2:11 p.m. + * Usage of any code found within this class is prohibited unless given explicit permission otherwise + */ +public final class GUIAdminLogs extends Gui { + + final List logs; + + public GUIAdminLogs(List logs) { + this.logs = logs; + + setTitle(TextUtils.formatText(Settings.GUI_LOGS_TITLE.getString())); + setRows(6); + setAcceptsItems(false); + draw(); + } + + private void draw() { + reset(); + + pages = (int) Math.max(1, Math.ceil(this.logs.size() / (double) 45)); + setPrevPage(5, 3, new TItemBuilder(Objects.requireNonNull(Settings.GUI_BACK_BTN_ITEM.getMaterial().parseMaterial())).setName(Settings.GUI_BACK_BTN_NAME.getString()).setLore(Settings.GUI_BACK_BTN_LORE.getStringList()).toItemStack()); + setNextPage(5, 5, new TItemBuilder(Objects.requireNonNull(Settings.GUI_NEXT_BTN_ITEM.getMaterial().parseMaterial())).setName(Settings.GUI_NEXT_BTN_NAME.getString()).setLore(Settings.GUI_NEXT_BTN_LORE.getStringList()).toItemStack()); + setOnPage(e -> draw()); + + int slot = 0; + List data = this.logs.stream().sorted(Comparator.comparingLong(AuctionAdminLog::getTime).reversed()).skip((page - 1) * 45L).limit(45).collect(Collectors.toList()); + + for (AuctionAdminLog log : data) { + setItem(slot++, ConfigurationItemHelper.createConfigurationItem(log.getItem(), AuctionAPI.getInstance().getItemName(log.getItem()), Settings.GUI_LOGS_LORE.getStringList(), new HashMap() {{ + put("%admin%", log.getAdminName()); + put("%target%", log.getTargetName()); + put("%admin_uuid%", log.getAdmin()); + put("%target_uuid%", log.getTarget()); + put("%item_id%", log.getItemId()); + put("%admin_action%", log.getAdminAction().getTranslation()); + put("%admin_log_date%", AuctionAPI.getInstance().convertMillisToDate(log.getTime())); + }})); + } + } +} diff --git a/src/main/java/ca/tweetzy/auctionhouse/listeners/AuctionListeners.java b/src/main/java/ca/tweetzy/auctionhouse/listeners/AuctionListeners.java index 4c5a200..dfc2ed3 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/listeners/AuctionListeners.java +++ b/src/main/java/ca/tweetzy/auctionhouse/listeners/AuctionListeners.java @@ -2,6 +2,7 @@ package ca.tweetzy.auctionhouse.listeners; import ca.tweetzy.auctionhouse.AuctionHouse; import ca.tweetzy.auctionhouse.api.AuctionAPI; +import ca.tweetzy.auctionhouse.api.events.AuctionAdminEvent; import ca.tweetzy.auctionhouse.api.events.AuctionBidEvent; import ca.tweetzy.auctionhouse.api.events.AuctionEndEvent; import ca.tweetzy.auctionhouse.api.events.AuctionStartEvent; @@ -11,6 +12,7 @@ import ca.tweetzy.auctionhouse.settings.Settings; import ca.tweetzy.auctionhouse.transaction.Transaction; import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import java.util.UUID; @@ -98,4 +100,10 @@ public class AuctionListeners implements Listener { AuctionAPI.getInstance().sendDiscordBidMessage(hook, e.getAuctionedItem(), e.getNewBidAmount()); }), 1L); } + + @EventHandler + public void onAdminAction(AuctionAdminEvent event) { + if (!Settings.LOG_ADMIN_ACTIONS.getBoolean()) return; + AuctionHouse.getInstance().getDataManager().insertLogAsync(event.getAuctionAdminLog()); + } } diff --git a/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java b/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java index 147623a..5057927 100644 --- a/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java +++ b/src/main/java/ca/tweetzy/auctionhouse/settings/Settings.java @@ -559,6 +559,18 @@ public class Settings { public static final ConfigSetting GUI_TRANSACTIONS_TYPE_ITEMS_SELF_TRANSACTIONS_LORE = new ConfigSetting(config, "gui.transactions type.items.self transactions.lore", Collections.singletonList("&7Click to view all your transactions")); + /* =============================== + * LOGS LIST GUI + * ===============================*/ + public static final ConfigSetting GUI_LOGS_TITLE = new ConfigSetting(config, "gui.admin logs.title", "&7&LAdmin Logs"); + public static final ConfigSetting GUI_LOGS_LORE = new ConfigSetting(config, "gui.admin logs.lore", Arrays.asList( + "&7Admin&F: &e%admin%", + "&7Target&F: &e%target%", + "&7Item ID&F: %item_id%", + "&7Action&F: &e%admin_action%", + "&7Date&F: &e%admin_log_date%" + )); + /* =============================== * TRANSACTIONS LIST GUI * ===============================*/