From 2a530435e8fabc4d4391f13678710de5cccfb057 Mon Sep 17 00:00:00 2001 From: Greazi Date: Fri, 15 Dec 2023 16:49:05 +0100 Subject: [PATCH 1/2] update .gitignore --- .gitignore | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 9268b2e0..a7dcce6d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,22 @@ -*.DS_Store -*.iml +################# +## IDEA +################# + +# User-specific stuff .idea/ +.idea_modules/ .gradle/ +*.iml +*.DS_Store +.run/ + +# IntelliJ out/ -build/ \ No newline at end of file +target/ +settings.yaml + +techBotSettings.yaml + +Archive/ + +target/ From 8e71d5ec466018c76859100c9de0a67fd8ee92a8 Mon Sep 17 00:00:00 2001 From: Greazi Date: Fri, 15 Dec 2023 16:49:41 +0100 Subject: [PATCH 2/2] Updated to V2 --- LICENSE.md | 2 + build.gradle | 63 -- build.properties | 0 gradle/wrapper/gradle-wrapper.jar | Bin 58695 -> 0 bytes gradle/wrapper/gradle-wrapper.properties | 5 - gradlew | 183 ---- gradlew.bat | 100 --- pom.xml | 105 +++ settings.gradle | 3 - .../TechDiscordBot/TechDiscordBot.java | 495 +++++------ .../actions/buttons/ApplyButton.java | 153 ++++ .../actions/buttons/BotActionButtons.java | 64 ++ .../actions/buttons/DeleteButton.java | 36 + .../actions/buttons/TicketButtons.java | 63 ++ .../buttons/verification/VerifyButton.java | 25 + .../actions/menus/ApplyMenu.java | 110 +++ .../actions/menus/RolesMenu.java | 112 +++ .../actions/menus/SelfRolesMenu.java | 155 ++++ .../actions/menus/TicketMenus.java | 718 ++++++++++++++++ .../actions/modals/ApplicationModal.java | 371 +++++++++ .../actions/modals/ShutdownModal.java | 61 ++ .../actions/modals/TicketModal.java | 64 ++ .../actions/modals/VerificationModal.java | 192 +++++ .../actions/modals/VerificationPreModal.java | 107 +++ .../TechDiscordBot/client/APIClient.java | 15 - .../applications/ApplicationCommand.java | 79 ++ .../commands/common/AnswerCommand.java | 73 ++ .../commands/common/GoogleCommand.java | 88 ++ .../commands/common/LinkCommand.java | 90 ++ .../commands/common/PluginCommand.java | 59 ++ .../commands/common/PreorderCommand.java | 107 +++ .../commands/common/RemindCommand.java | 66 ++ .../commands/common/SubVerifyCommand.java | 21 + .../commands/common/WikiCommand.java | 100 +++ .../commands/console/SayConsoleCommand.java | 39 + .../commands/debug/DatabaseCommand.java | 109 +++ .../commands/staff/BotCommands.java | 142 ++++ .../commands/staff/PruneCommand.java | 123 +++ .../commands/staff/QuestionCommand.java | 192 +++++ .../commands/staff/RoleCommand.java | 81 ++ .../commands/staff/UpdateCommand.java | 56 ++ .../commands/staff/UserInfoCommand.java | 55 ++ .../commands/staff/punishment/BanCommand.java | 88 ++ .../staff/punishment/KickCommand.java | 77 ++ .../staff/punishment/TimeoutCommand.java | 143 ++++ .../staff/punishment/WarnCommand.java | 87 ++ .../commands/tickets/TicketCommand.java | 112 +++ .../commands/tickets/TicketStaffCommand.java | 390 +++++++++ .../verification/CheckAccountCommand.java | 34 + .../commands/verification/CodeCommand.java | 33 + .../TechDiscordBot/database/Database.java | 22 + .../database/TranscriptDatabase.java | 12 + .../database/TranscriptSqlManager.java | 94 +++ .../database/entities/SqlApplication.java | 65 ++ .../database/entities/SqlMember.java | 45 + .../database/entities/SqlPatreon.java | 58 ++ .../database/entities/SqlPreorder.java | 49 ++ .../database/entities/SqlReminder.java | 75 ++ .../database/entities/SqlTicket.java | 80 ++ .../database/entities/SqlTranscript.java | 28 + .../entities/verification/SqlPurchase.java | 54 ++ .../verification/SqlVerification.java | 55 ++ .../database/tables/ApplicationsTable.java | 114 +++ .../database/tables/MembersTable.java | 80 ++ .../database/tables/PatreonTable.java | 120 +++ .../database/tables/Preorders.java | 35 + .../database/tables/Purchases.java | 90 ++ .../database/tables/Reminders.java | 70 ++ .../database/tables/Tickets.java | 161 ++++ .../database/tables/Transcripts.java | 39 + .../database/tables/Verifications.java | 114 +++ .../TechDiscordBot/github/GitHubUtil.java | 65 -- .../TechDiscordBot/github/GithubRelease.java | 36 - .../TechDiscordBot/logs/PunishLogs.java | 55 -- .../TechDiscordBot/logs/RoleLogs.java | 55 -- .../TechDiscordBot/logs/ServerLogs.java | 55 -- .../TechDiscordBot/logs/TicketLogs.java | 55 -- .../TechDiscordBot/logs/TranscriptLogs.java | 55 -- .../TechDiscordBot/logs/VerificationLogs.java | 55 -- .../TechsCode/TechDiscordBot/model/Logs.java | 328 ++++++++ .../TechDiscordBot/model/Pastebin.java | 47 ++ .../model/enums/Application.java | 254 ++++++ .../model/enums/Marketplace.java | 70 ++ .../TechDiscordBot/model/enums/Patreon.java | 25 + .../TechDiscordBot/model/enums/Plugin.java | 152 ++++ .../TechDiscordBot/model/enums/Ticket.java | 248 ++++++ .../reminders/HumanTimeBuilder.java | 20 +- .../model/reminders/Reminder.java | 83 ++ .../reminders/ReminderArgResponse.java | 2 +- .../model/reminders/ReminderManager.java | 110 +++ .../model/reminders/ReminderTimeType.java | 40 + .../{ => model}/reminders/ReminderType.java | 2 +- .../module/CommandCategory.java | 7 - .../TechDiscordBot/module/CommandModule.java | 38 - .../TechDiscordBot/module/Module.java | 48 -- .../TechDiscordBot/module/ModulesManager.java | 129 --- .../module/cmds/APICommand.java | 44 - .../module/cmds/AddonCommand.java | 44 - .../module/cmds/BanCommand.java | 103 --- .../module/cmds/CheckWarnsCommand.java | 75 -- .../module/cmds/CodeCommand.java | 54 -- .../module/cmds/DeleteWarnCommand.java | 80 -- .../module/cmds/FeedbackCommand.java | 49 -- .../module/cmds/GetReleaseCommand.java | 109 --- .../module/cmds/GuidesCommand.java | 44 - .../module/cmds/HowtoCommand.java | 81 -- .../module/cmds/InsaneEditorCommand.java | 46 - .../module/cmds/KickCommand.java | 85 -- .../module/cmds/MCMarketCommand.java | 46 - .../module/cmds/MuteCommand.java | 97 --- .../module/cmds/OverviewCommand.java | 136 --- .../module/cmds/PastebinCommand.java | 44 - .../module/cmds/PatreonCommand.java | 48 -- .../module/cmds/PluginCommand.java | 59 -- .../module/cmds/PolymartCommand.java | 46 - .../module/cmds/PreorderCommand.java | 140 ---- .../module/cmds/PruneCommand.java | 96 --- .../module/cmds/RemindMeCommand.java | 86 -- .../module/cmds/RoleCommand.java | 140 ---- .../module/cmds/RulesCommand.java | 210 ----- .../module/cmds/SongodaCommand.java | 46 - .../module/cmds/SpigotCommand.java | 46 - .../module/cmds/StatusCommand.java | 127 --- .../module/cmds/SubVerifyCommand.java | 215 ----- .../module/cmds/UserInfoCommand.java | 66 -- .../module/cmds/WarnCommand.java | 100 --- .../module/cmds/WikiCommand.java | 128 --- .../module/modules/ActivitiesModule.java | 134 --- .../module/modules/ChatLogModule.java | 101 --- .../module/modules/EventsModule.java | 64 -- .../module/modules/PluginLabModule.java | 158 ---- .../module/modules/PreorderModule.java | 83 -- .../module/modules/ReactionModule.java | 115 --- .../module/modules/RoleAssignerModule.java | 181 ---- .../module/modules/ServerStatusModule.java | 57 -- .../module/modules/StaffEmbedModule.java | 94 --- .../modules/SupportWrongChannelModule.java | 143 ---- .../module/modules/TicketModule.java | 563 ------------- .../module/modules/UrlWhitelistModule.java | 171 ---- .../module/modules/VerificationModule.java | 243 ------ .../module/modules/WordBlacklistModule.java | 154 ---- .../TechDiscordBot/modules/ApplyModule.java | 224 +++++ .../modules/BotMentionModule.java | 30 + .../TechDiscordBot/modules/ChatLogModule.java | 47 ++ .../modules/MemberJoinModule.java | 39 + .../modules/MemberLeaveModule.java | 36 + .../modules/MessageReceive.java | 433 ++++++++++ .../modules/PluginLabModule.java | 20 + .../modules/PreorderModule.java | 80 ++ .../modules/PrivateMessageReceiveModule.java | 26 + .../TechDiscordBot/modules/RolesModule.java | 112 +++ .../modules/StaffEmbedModule.java | 20 + .../TechDiscordBot/modules/TicketModule.java | 373 +++++++++ .../modules/VerificationModule.java | 118 +++ .../modules/WrongChannelModule.java | 20 + .../modules/serverStatusModule.java | 20 + .../TechsCode/TechDiscordBot/mysql/MySQL.java | 83 -- .../TechDiscordBot/mysql/MySQLSettings.java | 38 - .../TechDiscordBot/mysql/storage/Mute.java | 60 -- .../mysql/storage/Preorder.java | 35 - .../TechDiscordBot/mysql/storage/Storage.java | 379 --------- .../mysql/storage/Verification.java | 25 - .../TechDiscordBot/mysql/storage/Warning.java | 76 -- .../TechDiscordBot/objects/ChannelQuery.java | 24 - .../TechDiscordBot/objects/Cooldown.java | 22 - .../TechDiscordBot/objects/DefinedQuery.java | 17 - .../TechDiscordBot/objects/Query.java | 66 -- .../TechDiscordBot/objects/Requirement.java | 27 - .../objects/TicketPriority.java | 18 - .../TechDiscordBot/reminders/Reminder.java | 79 -- .../reminders/ReminderManager.java | 102 --- .../reminders/ReminderTimeType.java | 40 - .../TechDiscordBot/settings/Settings.java | 256 ++++++ .../songoda/SongodaAPIClient.java | 93 --- .../songoda/SongodaPurchase.java | 45 - .../songoda/SongodaPurchaseList.java | 47 -- .../spigotmc/SpigotAPIManager.java | 444 ---------- .../TechDiscordBot/spigotmc/SpigotApi.java | 115 --- .../spigotmc/data/APIStatus.java | 90 -- .../spigotmc/data/APIWebStatus.java | 42 - .../TechDiscordBot/spigotmc/data/Cost.java | 43 - .../spigotmc/data/ProfileComment.java | 34 - .../spigotmc/data/Purchase.java | 65 -- .../spigotmc/data/Resource.java | 110 --- .../TechDiscordBot/spigotmc/data/Review.java | 61 -- .../TechDiscordBot/spigotmc/data/Time.java | 63 -- .../TechDiscordBot/spigotmc/data/Update.java | 67 -- .../TechDiscordBot/spigotmc/data/User.java | 40 - .../data/lists/ProfileCommentList.java | 24 - .../spigotmc/data/lists/PurchasesList.java | 36 - .../spigotmc/data/lists/ResourcesList.java | 37 - .../spigotmc/data/lists/ReviewsList.java | 32 - .../spigotmc/data/lists/UpdatesList.java | 24 - .../transcripts/TicketTranscript.java | 12 +- .../TicketTranscriptMessageType.java | 2 +- .../transcripts/TicketTranscriptOptions.java | 2 +- .../TechsCode/TechDiscordBot/util/Config.java | 113 --- .../TechDiscordBot/util/ConsoleColor.java | 70 -- .../util/PasswordGenerator.java | 42 - .../TechsCode/TechDiscordBot/util/Plugin.java | 212 ----- .../util/PluginMarketplace.java | 79 -- .../TechDiscordBot/util/ProjectUtil.java | 61 -- .../TechDiscordBot/util/PterodactylAPI.java | 49 -- .../TechDiscordBot/util/TechEmbedBuilder.java | 210 ----- .../TechDiscordBot/utils/Changelog.java | 62 ++ .../TechDiscordBot/utils/HumanTime.java | 788 ++++++++++++++++++ .../TechDiscordBot/utils/JsonReader.java | 118 +++ .../TechDiscordBot/utils/ProjectUtil.java | 143 ++++ 208 files changed, 10792 insertions(+), 9719 deletions(-) create mode 100644 LICENSE.md delete mode 100644 build.gradle delete mode 100644 build.properties delete mode 100644 gradle/wrapper/gradle-wrapper.jar delete mode 100644 gradle/wrapper/gradle-wrapper.properties delete mode 100755 gradlew delete mode 100644 gradlew.bat create mode 100644 pom.xml delete mode 100644 settings.gradle create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/ApplyButton.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/BotActionButtons.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/DeleteButton.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/TicketButtons.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/verification/VerifyButton.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/menus/ApplyMenu.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/menus/RolesMenu.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/menus/SelfRolesMenu.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/menus/TicketMenus.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ApplicationModal.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ShutdownModal.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/modals/TicketModal.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationModal.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationPreModal.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/client/APIClient.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/applications/ApplicationCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/AnswerCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/GoogleCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/LinkCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/PluginCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/PreorderCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/RemindCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/SubVerifyCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/common/WikiCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/console/SayConsoleCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/debug/DatabaseCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/BotCommands.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/PruneCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/QuestionCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/RoleCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UpdateCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UserInfoCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/BanCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/KickCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/TimeoutCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/WarnCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketStaffCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CheckAccountCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CodeCommand.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/Database.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptDatabase.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptSqlManager.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlApplication.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlMember.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPatreon.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPreorder.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlReminder.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTicket.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTranscript.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlPurchase.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlVerification.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/ApplicationsTable.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/MembersTable.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/PatreonTable.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/Preorders.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/Purchases.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/Reminders.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/Tickets.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/Transcripts.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/database/tables/Verifications.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/github/GitHubUtil.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/github/GithubRelease.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/logs/PunishLogs.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/logs/RoleLogs.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/logs/ServerLogs.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/logs/TicketLogs.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/logs/TranscriptLogs.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/logs/VerificationLogs.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/Logs.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/Pastebin.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/enums/Application.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/enums/Marketplace.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/enums/Patreon.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/enums/Plugin.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/enums/Ticket.java rename src/main/java/me/TechsCode/TechDiscordBot/{ => model}/reminders/HumanTimeBuilder.java (86%) create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/reminders/Reminder.java rename src/main/java/me/TechsCode/TechDiscordBot/{ => model}/reminders/ReminderArgResponse.java (90%) create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderManager.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderTimeType.java rename src/main/java/me/TechsCode/TechDiscordBot/{ => model}/reminders/ReminderType.java (77%) delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/CommandCategory.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/CommandModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/Module.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/ModulesManager.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/APICommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/AddonCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/BanCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CheckWarnsCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CodeCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/DeleteWarnCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/FeedbackCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GetReleaseCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GuidesCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/HowtoCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/InsaneEditorCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/KickCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MCMarketCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MuteCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/OverviewCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PastebinCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PatreonCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PluginCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PolymartCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PreorderCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PruneCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RemindMeCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RoleCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RulesCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SongodaCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SpigotCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/StatusCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SubVerifyCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/UserInfoCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WarnCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WikiCommand.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/ActivitiesModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/ChatLogModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/EventsModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/PluginLabModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/PreorderModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/ReactionModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/RoleAssignerModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/ServerStatusModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/StaffEmbedModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/SupportWrongChannelModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/TicketModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/UrlWhitelistModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/VerificationModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/module/modules/WordBlacklistModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/ApplyModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/BotMentionModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/ChatLogModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/MemberJoinModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/MemberLeaveModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/MessageReceive.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/PluginLabModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/PreorderModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/PrivateMessageReceiveModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/RolesModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/StaffEmbedModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/TicketModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/VerificationModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/WrongChannelModule.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/modules/serverStatusModule.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQL.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQLSettings.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Mute.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Preorder.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Storage.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Verification.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Warning.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/objects/ChannelQuery.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/objects/Cooldown.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/objects/DefinedQuery.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/objects/Query.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/objects/Requirement.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/objects/TicketPriority.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/reminders/Reminder.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderManager.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderTimeType.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/settings/Settings.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaAPIClient.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchase.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchaseList.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotAPIManager.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotApi.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIStatus.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIWebStatus.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Cost.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/ProfileComment.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Purchase.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Resource.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Review.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Time.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Update.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/User.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ProfileCommentList.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/PurchasesList.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ResourcesList.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ReviewsList.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/UpdatesList.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/Config.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/ConsoleColor.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/PasswordGenerator.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/Plugin.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/PluginMarketplace.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/ProjectUtil.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/PterodactylAPI.java delete mode 100644 src/main/java/me/TechsCode/TechDiscordBot/util/TechEmbedBuilder.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/utils/Changelog.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/utils/HumanTime.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/utils/JsonReader.java create mode 100644 src/main/java/me/TechsCode/TechDiscordBot/utils/ProjectUtil.java diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 00000000..e4b25766 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,2 @@ + +Copyright (C) 2022 [Greazi](https://greazi.com) diff --git a/build.gradle b/build.gradle deleted file mode 100644 index c5c85749..00000000 --- a/build.gradle +++ /dev/null @@ -1,63 +0,0 @@ -apply plugin: 'java' -apply plugin: 'com.github.johnrengelman.shadow' - -group = "me.TechsCode" - -compileJava.options.encoding = 'UTF-8' - -assemble.dependsOn shadowJar - -repositories { - mavenLocal() - mavenCentral() - - maven { url 'https://www.jitpack.io' } - maven { url 'https://m2.dv8tion.net/releases'} - maven { url 'https://repo.mattmalec.com/repository/releases'} -} - -dependencies { - implementation ('net.dv8tion:JDA:4.3.0_331') { exclude module: 'opus-java' } - - implementation 'com.google.guava:guava:31.1-jre' - implementation 'org.jsoup:jsoup:1.14.3' - implementation 'org.apache.commons:commons-lang3:3.12.0' - implementation 'mysql:mysql-connector-java:8.0.29' - implementation "com.googlecode.json-simple:json-simple:1.1.1" - implementation 'net.sourceforge.htmlunit:htmlunit:2.62.0' - implementation 'com.google.code.gson:gson:2.9.0' - implementation 'org.kohsuke:github-api:1.306' - implementation 'com.mattmalec:Pterodactyl4J:2.BETA_78' -} - -buildscript { - repositories { - maven { - url "https://plugins.gradle.org/m2/" - } - } - dependencies { - classpath 'com.github.jengelman.gradle.plugins:shadow:4.0.4' - } -} - -shadowJar { - archiveFileName = 'TechDiscordBot.jar' - destinationDirectory = file("build") -} - -jar { - exclude 'META-INF/*.SF', 'META-INF/*.DSA', 'META-INF/*.RSA', 'META-INF/*.MF' - manifest { - attributes 'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ') - attributes 'Main-Class': 'me.TechsCode.TechDiscordBot.TechDiscordBot' - } -} - -tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' - manifest { - attributes 'Class-Path': configurations.runtime.files.collect { "lib/$it.name" }.join(' ') - attributes 'Main-Class': 'me.TechsCode.TechDiscordBot.TechDiscordBot' - } -} \ No newline at end of file diff --git a/build.properties b/build.properties deleted file mode 100644 index e69de29b..00000000 diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index f3d88b1c2faf2fc91d853cd5d4242b5547257070..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 58695 zcma&OV~}Oh(k5J8>Mq;vvTfV8ZQE5{wr$(iDciPf+tV}m-if*I+;_h3N1nY;M6TF7 zBc7A_WUgl&IY|&uNFbnJzkq;%`2QLZ5b*!{1OkHidzBVe;-?mu5upVElKVGD>pC88 zzP}E3wRHBgaO?2nzdZ5pL;m-xf&RU>buj(E-s=DK zf%>P9se`_emGS@673tqyT^;o8?2H}$uO&&u^TlmHfPgSSfPiTK^AZ7DTPH`Szw4#- z&21E&^c|dx9f;^@46XDX9itS+ZRYuqx#wG*>5Bs&gxwSQbj8grds#xkl;ikls1%(2 zR-`Tn(#9}E_aQ!zu~_iyc0gXp2I`O?erY?=JK{M`Ew(*RP3vy^0=b2E0^PSZgm(P6 z+U<&w#)I=>0z=IC4 zh4Q;eq94OGttUh7AGWu7m){;^Qk*5F6eTn+Ky$x>9Ntl~n0KDzFmB0lBI6?o!({iX zQt=|-9TPjAmCP!eA{r|^71cIvI(1#UCSzPw(L2>8OG0O_RQeJ{{MG)tLQ*aSX{AMS zP-;|nj+9{J&c9UV5Ww|#OE*Ah6?9WaR?B04N|#`m0G-IqwdN~Z{8)!$@UsK>l9H81 z?z`Z@`dWZEvuABvItgYLk-FA(u-$4mfW@2(Eh(9fe`5?WUda#wQa54 z3dXE&-*@lsrR~U#4NqkGM7Yu4#pfGqAmxmGr&Ep?&MwQ9?Z*twtODbi;vK|nQ~d_N z;T5Gtj_HZKu&oTfqQ~i`K!L||U1U=EfW@FzKSx!_`brOs#}9d(!Cu>cN51(FstP_2dJh>IHldL~vIwjZChS-*KcKk5Gz zyoiecAu;ImgF&DPrY6!68)9CM-S8*T5$damK&KdK4S6yg#i9%YBH>Yuw0f280eAv3 za@9e0+I>F}6&QZE5*T8$5__$L>39+GL+Q(}j71dS!_w%B5BdDS56%xX1~(pKYRjT; zbVy6V@Go&vbd_OzK^&!o{)$xIfnHbMJZMOo``vQfBpg7dzc^+&gfh7_=oxk5n(SO3 zr$pV6O0%ZXyK~yn++5#x`M^HzFb3N>Vb-4J%(TAy#3qjo2RzzD*|8Y} z7fEdoY5x9b3idE~-!45v?HQ$IQWc(c>@OZ>p*o&Om#YU904cMNGuEfV=7=&sEBWEO z0*!=GVSv0>d^i9z7Sg{z#So+GM2TEu7$KXJ6>)Bor8P5J(xrxgx+fTLn1?Jlotz*U z(ekS*a2*ml5ft&R;h3Gc2ndTElB!bdMa>UptgIl{pA+&b+z_Y&aS7SWUlwJf-+PRv z$#v|!SP92+41^ppe}~aariwztUtwKA8BBLa5=?j3@~qHfjxkvID8CD`t5*+4s|u4T zLJ9iEfhO4YuAl$)?VsWcln|?(P=CA|!u}ab3c3fL8ej9fW;K|@3-c@y4I;^8?K!i0 zS(5Cm#i85BGZov}qp+<-5!Fh+KZev3(sA2D_4Z~ZLmB5B$_Yw2aY{kA$zuzggbD{T zE>#yd3ilpjM4F^dmfW#p#*;@RgBg{!_3b6cW?^iYcP!mjj!}pkNi{2da-ZCD2TKKz zH^x^+YgBb=dtg@_(Cy33D|#IZ&8t?w8$E8P0fmX#GIzq~w51uYmFs{aY76e0_~z2M z(o%PNTIipeOIq(H5O>OJ*v8KZE>U@kw5(LkumNrY>Rv7BlW7{_R9v@N63rK)*tu|S zKzq|aNs@81YUVZ5vm>+pc42CDPwQa>oxrsXkRdowWP!w?=M(fn3y6frEV*;WwfUV$s31D!S_;_~E@MEZ>|~wmIr05#z2J+& zBme6rnxfCp&kP@sP)NwG>!#WqzG>KN7VC~Gdg493So%%-P%Rk!<|~-U|L3VASMj9K zk(Pfm1oj~>$A>MFFdAC8M&X0i9-cV7Q($(R5C&nR5RH$T&7M=pCDl`MpAHPOha!4r zQnYz$7B1iLK$>_Ai%kZQaj-9)nH$)tESWUSDGs2|7plF4cq1Oj-U|+l4Ga}>k!efC z*ecEudbliG+%wI8J#qI!s@t%0y9R$MBUFB)4d47VmI`FjtzNd_xit&l1T@drx z&4>Aj<2{1gUW8&EihwT1mZeliwrCN{R|4@w4@@Btov?x5ZVzrs&gF0n4jGSE33ddUnBg_nO4Zw)yB$J-{@a8 z);m%fvX2fvXxogriNb}}A8HxA)1P-oK+Da4C3pofK3>U_6%DsXFpPX}3F8O`uIpLn zdKjq(QxJTJ4xh->(=lxWO#^XAa~<7UxQl8~8=izS!TcPmAiBP5Et7y?qEbFd9Q=%IJ;%Kn$lto-~3`}&`x=AVS+Uo7N*hbUxhqVH_w^sn!74z{Ka#*U6s z=8jIrHpUMBC@@9Jn~GS<$lse*EKuX%3Swl5&3~GiK_$vn8Vjqe{mjhBlH}m4I8qK+ ztU50COh7)d-gXpq-|}T;biGa^e=VjxjjFuoGIA8`2jJ}wNBRcsx24?7lJ7W4ksNPv zA7|gcXT@~7KTID#0|EX#OAXvgaBJ8Jg!7X#kc1^Tvl;I(=~(jtn-(5bhB=~J^w5bw z8^Hifeupm;nwsSDkT{?x?E(DgLC~Nh8HKQGv`~2jMYrz9PwS^8qs3@nz4ZBCP5}%i z=w}jr2*$X-f(zDhu%D8(hWCpix>TQpi{e`-{p^y?x4?9%)^wWc?L}UMcfp~lL|;g) zmtkcXGi9#?cFOQQi_!Z8b;4R%4y{$SN~fkFedDJ&3eBfHg|DRSx09!tjoDHgD510Z z_aJLHdS&7;Dl;X|WBVyl_+d+2_MK07^X1JEi_)v$Z*ny-()VrD6VWx|Un{)gO0*FQ zX{8Ss3JMrV15zXyfCTsVO@hs49m&mN(QMdL3&x@uQqOyh2gnGJYocz0G=?BX7qxA{ zXe0bn4ij^;wfZfnRlIYkWS^usYI@goI9PccI>}Ih*B!%zv6P$DoXsS%?G)|HHevkG z>`b#vtP=Lx$Ee(t??%_+jh(nuc0Q&mCU{E3U z1NqNK!XOE#H2Pybjg0_tYz^bzX`^RR{F2ML^+<8Q{a;t(#&af8@c6K2y2m zP|parK=qf`I`#YxwL=NTP>tMiLR(d|<#gEu=L-c!r&(+CpSMB5ChYW1pUmTVdCWw|!Ao?j&-*~50S`=) z9#Knf7GPA19g%Y7wip@`nj$aJcV|SakXZ*Q2k$_SZlNMx!eY8exF;navr&R)?NO9k z#V&~KLZ0c9m|Mf4Gic}+<=w9YPlY@|Pw*z?70dwOtb<9-(0GOg>{sZaMkZc9DVk0r zKt%g5B1-8xj$Z)>tWK-Gl4{%XF55_Ra3}pSY<@Y&9mw`1jW8|&Zm{BmHt^g=FlE{` z9Lu7fI2v3_0u~apyA;wa|S4NaaG>eHEw&3lNFVd_R9E=Y? zgpVQxc9{drFt2pP#ZiN~(PL%9daP4pWd*5ABZYK{a@e&Vb`TYiLt$1S>KceK36Ehz z;;MI%V;I`#VoSVAgK3I%-c>ViA>nt=5EZ zjr$Jv~$_vg<$q<@CpZ1gdqP_3v^)uaqZ`?RS_>f(pWx3(H;gWpjR?W8L++YPW;)Vw3)~tozdySrB3A2;O<%1F8?Il4G|rO0mEZYHDz!?ke!$^bEiWRC1B%j~ws0+hHS;B8l5Wh)e+Ms7f4M4CbL%Q_*i~cP}5-B(UkE&f7*pW6OtYk5okQCEoN4v|7;(+~~nyViqo5 z(bMGQi$)KN6EmfVHv4pf2zZMJbcAKyYy>jY@>LB5eId|2Vsp{>NMlsee-tmh({;@b z@g;wiv8@a1qrDf-@7$(MR^M^*dKYBewhIDFX%;*8s zR#u?E;DJO;VnTY6IfbO=dQ61V0DisUAs4~t|9`9ZE(jG}ax#-xikDhsO_4^RaK ziZ?9AJQP_{9WuzVk^s_U+3V8gOvVl5(#1>}a|RL>};+uJB%nQM-J>M4~yK)cioytFXtnmOaJZSiE+3g}C`Im~6H z*+-vjI>ng5w>>Y!L(+DwX2gs0!&-BFEaDie4i5ln*NGP$te7$F9iUlJl4`XpkAsPm z0l?GQ17uN^=g~u1*$)S`30xL%!`LW*flwT*#svAtY(kHXFfvA`dj*pDfr0pBZ`!La zWmX$Z@qyv|{nNsRS|+CzN-Pvb>47HEDeUGFhpp5C_NL0Vp~{Wc{bsm_5J!#tuqW@? z)Be zb&Gj&(l*bHQDq7w-b`F9MHEH*{Dh~0`Gn8t`pz}!R+q~4u$T@cVaUu`E^%0f-q*hM z1To6V31UGJN7a-QW5;nhk#C26vmHyjTVZkdV zqYMI9jQY)3oZt=V0L7JZQ=^c2k){Y_lHp&V_LIi*iX^Ih3vZ_K<@Di(hY<&g^f?c$wwF-wX1VLj>ZC4{0#e`XhbL_$a9uXS zKph*4LupSV2TQBCJ4AfOXD8fs2;bAGz-qU4=Qj$^1ZJX z2TtaVdq>OjaWGvv9)agwV)QW9eTZ-xv`us2!yXSARnD5DwX_Vg*@g4w!-zT|5<}-7 zsnllGRQz>k!LwdU`|i&!Bw^W7CTUU3x`Zg8>XgHj=bo!cd<#pI8*pa*1N`gg~I0ace!wzZoJ)oGScm~D_Sc;#wFed zUo;-*0LaWVCC2yqr6IbeW3`hvXyMfAH94qP2|cN``Z%dSuz8HcQ!WT0k38!X34<6l zHtMV%4fH5<6z-lYcK;CTvzzT6-^xSP>~a*8LfbByHyp$|X*#I6HCAi){gCu1nvN%& zvlSbNFJRCc&8>f`$2Qa`fb@w!C11v1KCn)P9<}ei0}g*cl~9A9h=7(}FO!=cVllq3 z7nD)E%gt;&AYdo{Ljb2~Fm5jy{I><%i*GUlU8crR4k(zwQf#nima@xb%O71M#t-4< z(yjX(m^mp_Y;5()naqt2-VibylPS)Oof9uBp$3Gj`>7@gjKwnwRCc>rx%$esn);gI z5B9;~uz57n7Rpm8K^o=_sFPyU?>liHM&8&#O%f)}C5F7gvj#n#TLp@!M~Q?iW~lS}(gy%d&G3p?iBP z(PZQUv07@7!o3~1_l|m5m;Xr)^QK_JaVAY3v1UREC*6>v;AT$BO`nA~KZa1x3kV2F z%iwG7SaaAcT8kalCa^Hg&|eINWmBQA_d8$}B+-Q_@6j_{>a- zwT3CMWG!A}Ef$EvQsjK>o)lJ;q!~#F%wo`k-_mT=+yo%6+`iGe9(XeUl;*-4(`G;M zc@+ep^Xv&<3e7l4wt48iwaLIC1RhSsYrf6>7zXfVD zNNJ1#zM;CjKgfqCabzacX7#oEN{koCnq1-stV+-CMQ=ZX7Fpd*n9`+AEg9=p&q7mTAKXvcbo?$AVvOOp{F>#a;S?joYZl_f}BECS%u&0x!95DR;|QkR9i}`FEAsPb=)I z8nb=4iwjiLRgAF}8WTwAb^eA>QjL4Srqb#n zTwx^-*Z38Uzh@bX$_1tq>m{o8PBX*t3Lqaf$EBqiOU*2NFp{LJX#3}p9{|v{^Hg4f zlhllKI>F+>*%mu6i9V7TT*Wx-zdK z(p8faUOwGOm5mBC%UGA1jO0@IKkG;i&+6Ur8XR2ZuRb$*a}R^-H6eKxcYodlXsF`& z{NkO+;_Yh-Ni@vV9iyzM43Yibn;oC7hPAzC24zs&+RYdY&r`3&&fg2hs62ysV^G`N zHMfBEFo8E3S$0C_m({bL8QCe$B@M{n1dLsaJYIU;(!n*V?0I1OvBB=iYh&`?u8 z&~n-$nbVIhO3mMhCQRlq%XRr1;Hvl=9E_F0sc9!VLnM>@mY~=Cx3K5}wxHKEZF9pC zIdyu1qucM!gEiomw7bW0-RwbX7?o=FE#K0l4`U2KhC8*kMWaEWJyVNZVu_tY2e&4F zb54Lh=Oz>(3?V$!ArXFXh8Cb3i;%KQGCrW$W#;kvx$YA2gofNeu?@nt>Yq8?2uJQp zUTo14hS%&dHF3Uhm~Z1>W)yb%&HoM!3z?%a%dmKT#>}}kKy2B=V3{Nu=bae%V%wU$ zb4%^m?&qn==QeHo`nAs3H}wtiK~!!&i|iBLfazh6!y9F)ToKNyE0B385!zq{p)5vB zvu`R#ULIS|2{3w52c*c$4}Pe>9Fw&U^>Bb_LUWn!xPx3X-uQsv(b1XFvFzn#voq0* z5~o`V_G805QXdgAOwOjoqmZ?uzwBVYSNP0Ie8FL`P0VK1J4CzV@t&%0duHB{;yIL$FZ9 zz#s#%ZG6ya&AwE;0_~^$1K

Hnj76Oym1QVh(3qRgs)GmgnEt-KxP|nCFY3uezZn zmtR0CZ$Z_-+f07?lu_tr~IC{&U6+QOth>ZgYk4V2FI$B2V3`M`Jk zsr>>lupymPeK129PfpDt9?GA2;I>03Ktz8NxwvTroqu8oaRB&bXT}G=^2UyOW}(4H z;9sG^YwV8K7pC&&viM^X_pfeFoN!cIhrE>OPQ5E<4KKDyPhRV^BGb_^Y6GO6#w}c= zu`0fC-@F4qXQtnB^nPmfI7Uw0bLhY^09TCO+H2(nvg8jdPjMAi4oSX%GP3oeo0`ks z%DoV|waU-Q7_libJCwnnOL9~LoapKqFPpZx?5FygX zsA~*ZR7X=@i{smf?fgxbcY6Y`JvD50P=R;Xv^sANPRp-Hc8n~Wb*gLIaoZJ2Q^CFe z_=G}y&{_NXT|Ob??}$cF7)$oPQMaeN_va1f%>C>V2E01uDU=h~<_fQKjtnl_aho2i zmI|R9jrNdhtl+q*X@}>l08Izz&UJygYkbsqu?4OOclV{GI5h98vfszu2QPiF?{Tvh19u_-C^+NjdAq!tq&Rd`ejXw#` z@U15c$Nmylco)Yj4kctX{L+lz$&CqTT5~}Q>0r-Xe!m5+?du6R&XY|YD5r5C-k*`s zOq-NOg%}RJr5ZWV4)?EO%XzZg&e8qVFQ?40r=8BI-~L%9T7@_{1X@<7RjboXqMzsV z8FiSINMjV*vC^FCv_;`jdJ-{U1<_xjZg4g?ek z4FtsapW_vFGqiGcGHP%?8US~Dfqi8^ZqtHx!}0%dqZFg%nQB)8`mE$~;1)Fb76nFk z@rK#&>2@@)4vO&gb{9&~R8-_{8qz6Rmw`4zeckD(L9xq}{r(fUO0Zh-R(d#x{<0j| z?6xZ2sp3mWnC}40B~g2QinHs1CZqZH&`+x2yBLT8hF7oWNIs_#YK2cyHO6AoGRG|RM>Hyn(ddpXFPAOGh~^0zcat`%&WoEQf9)!@l*3Tt@m>Lb z6$+$c!zsy_=%L9!_;jfd`?VXDd*^Vn%G>n~V9Vr6+_D@#E+dWB#&zAE+6xJeDMr1j zV+Tp~ht!M%^6f?)LBf8U1O4G#CutR07SB>8C&_&;g3TdIR#~e~qRtwd>&)|-ztJJ#4y0|UMjhJZlS8gA zAA260zUh+!$+xMfWKs|Lr23bcy#)JNnY|?WOka&wTS7_u%*N7PrMl1Lp9gxJY%CF? zz4IA@VVxX{knZPlNF+$9)>YIj#+(|$aflt=Wnforgn6`^3T+vaMmbshBjDi&tR(a7 zky~xCa77poRXPPam)@_UCwPdha^X~Aum=c0I@yTyD&Z!3pkA7LKr%Y6g%;~0<`{2& zS7W$AY$Kd}3Tg9CJgx=_gKR59zTMROsos?PU6&ocyCwCs8Qx1R%2#!&5c%~B+APu( z<1EXfahbm{XtOBK%@2a3&!cJ6R^g|2iLIN1)C2|l=;uj%tgSHoq2ojec6_4@6b<8BYG1h-Pm_V6dkRB!{T?jwVIIj&;~b7#%5Ew=0Fx zc(p7D1TT&e=hVt4spli}{J6tJ^}WL>sb`k}&gz+6It`Yz6dZdI53%$TR6!kSK2CfT*Q$`P30 z;$+G$D*C$U(^kkeY!OWn$j@IUu0_a{bZQ=TCbHD1EtmZ0-IBR<_3=tT%cz$>EE!V}pvfn7EMWs^971+XK}~kxSc_ATJJD$?)1Gz^Jq!>Hz#KkdCJ~jb-Y*Xv01_}}=T_V-A1<3O!V9Ezf z%Lnjihb3>=ZV}jSeqNu5AAdVbe|`;|p<%W#-<$s1oDYrB;C({psqV>ENkhadsC{cfEx=teVSB`?FOs+}d#pssxP z(ihudAVu3%%!*vOIWY11fn1M0&W|(|<2lEShz|#%W|wV2qM%#+P9NOy1x8jytHpfU zh;_L^uiL<<$L@~NpRXSrkJgdC>9R=>FmVu3^#C?3H>P{ue=mcv7lBmnfA?mB|L)EF zHv%Nl|D}0Tb~JVnv$ZysvbD8zw)>|5NpW3foe!QHipV9>Zy`|<5?O+rsBr*nZ4OE} zUytv%Rw7>^moSMsSU?@&a9+OdVgzWZnD>QXcUd{dd7vad+=0Hy)4|0A`}rpCx6cu!Ee5AM=iJ?|6=pG^>q(ExotyZP3(2PGhgg6-FkkQHS?nHX(yU0NG;4foCV|&)7 z1YK!bnv%#5n<25|CZ>4r1nK=D39qMzLAja*^#CN(aBbMx${?Iur3t=g2EMK|KwOF?I@W~0y`al&TGqJ zwf#~(?!>@#|JbDjQV9ct%+51l%q|lcY&f{FV&ACRVW*%VY6G5DzTpC!e%=T30mvav zRk$JOTntNoxRv>PDlJG1X=uep&???K00ep|l_#7=YZPuRHYoM46Z$O=ZZuGy_njgC z>P@gd+zKH5SjpWQ!h_r*!ol1s{9DS@sD4}xgFxaw>|av!xrKzg?rGnhZ#uZeU~iod z3-i*Hl@7cge0);y{DCVU(Ni1zg{yE&CxYT7)@zJ%ZZABj-Fh}0au^)*aw`vpmym;( z5|JZ!EACYenKNXH%=Md{my$sI3!8^FgtqkMcUR%w_)EBdP5DZ64aCIR%K99tId6SU ziT8Ef)K%7{XuIpPi}N+&FCm$elE>oKY;3c$x+*mXy?~wt6~?ss$HGqCm=YL2xzVTQ zr>*2_F;7j{5}NUPQ(aY0+h~rOKN|IA28L7^4XjX!L0C^vFB+3R5*1+s@k7;4d#U=5 zXTy8JN^_BCx1a4O3HMa9rf@?Fz>>dq}uvkY7!c?oksgs~xrpCo1{}^PD?w}Ug z3MbfBtRi z$ze~eRSLW^6bDJJeAt^5El{T*i1*v9wX{T7`a2wAVA z%j>3m*g^lc*~GOHFNy?h7>f7mPU*)3J>yPosaGkok}2#?wX5d$9moM~{NTzLznVhX zKa}bFQt#De`atoWzj4Lb@ZCud_T9rA@6VcmvW(+X?oIaH-FDbEg#0Slwf|7f!zUO( z7EUzpBOODL&w~(tNt0z|<9}Filev&4y;SQPp+?kIvJgnpc!^eYmsWz1)^n`LmP&Ui z-Oi1J2&O|$I<^V@g2Z91l3OArSbCkYAD0Tuw-O(INJJ>t%`DfIj}6%zmO+=-L{b!P zLRKvZHBT=^`60YuZon~D$;8UDlb-5l8J=1erf$H(r~ryWFN)+yY@a;=CjeUGNmexR zN)@)xaHmyp$SJcl>9)buKst5_+XomJu34&QMyS zQR(N@C$@%EmfWB8dFN(@Z%xmRma@>QU}!{3=E`wrRCQ~W=Dwb}*CW8KxAJ;v@TAs3 zW}Pq5JPc)(C8Rths1LR}Bgcf6dPOX<#X08^QHkznM-S>6YF(siF;pf~!@)O{KR4q1_c`T9gxSEf`_;a-=bg6=8W zQ&t`BK^gsK-E0Jp{^gW&8F9k?L4<#}Y0icYT2r+Dvg!bnY;lNNCj_3=N=yd9cM9kY zLFg|R0X;NRMY%zD*DbAmFV`(V@IANtz4^_32CH*)XCc$A>P-v49$k@!o$8%Ug>3-- z$#Fpo9J>eUMKg>Cn+T0H!n0Hf#avZX4pp54cv}YcutP+CmKC~a745-zhZp`KNms;J zS3S49WEyS8gCRAY|B~6yDh*cehY52jOSA#MZmk2dzu`_XpBXx9jDf!H3~!`n zaGe=)1VkfIz?*$T3t>-Pwhrw447idZxrsi;ks;(NF>uVl12}zI(N~2Gxi)8yDv-TLgbZ;L&{ax&TBv;m@z6RcbakF^el{!&)<___n#_|XR%jedxzfXG!a2Eyi)4g zYAWkYK{bQzhm|=>4+*SLTG2<#7g-{oB48b05=?PeW;Jo3ebWlo5y5|cl?p8)~PVZqiT^A~w-V*st8kV%%Et1(}x(mE0br-#hyPspVehofF`{gjFXla1lrqXJqQKE9M)8Xe0ZO&s$}Q zBTPjH>N!UU%bRFqaX(O9KMoG$Zy|xt-kCDjz(E*VDaI={%q? zURR{qi>G^wNteX|?&ZfhK-93KZlPXmGMsPd1o?*f_ej~TkoQ#no}~&#{O=>RadgtR zvig@~IZMsm3)vOr`>TGKD&fbRoB*0xhK7|R?Jh-NzkmR}H6lJiAZTIM1#AXE1LOGx zm7j;4b(Lu6d6GwtnsCvImB8%KJD+8z?W{_bDEB$ulcKP*v;c z*Ymsd)aP+t$dAfC-XnbwDx3HXKrB{91~O}OBx)fsb{s-qXkY<@QK7p-q-aaX&F?GS z2};`CqoNJ$<0DuM2!NCbtIpJ9*1a8?PH#bnF#xf~AYOIc4dx1Bw@K=)9bRX;ehYs; z$_=Ro(1!iIM=kZDlHFB>Ef46#rUwLM%)(#oAG(gYp>0tc##V{#aBl!q``!iIe1GBn z+6^G^5)(nr z8h#bm1ZzI450T?!EL)>RWX8VwT1X`2f;dW!{b~S>#$Pa~D6#Hp!;85XzluH%v5325 z730-aW?rY1!EAt;j7d23qfbMEyRZqxP};uID8xmG@mGw~3#2T^B~~14K5?&dP&H@r zL|aXJsEcAAXEXfu2d-!otZTV=if~^EQD*!NkUFQaheV&b-?-zH6JfjKO)aYN=Do*5 zYZ-@m#)5U0c&sUqu_%-Editr5#%Ne&bs)DxOj2_}`f;I_ReEY9U&Cf3rb>A3LK(ZD zid0_-3RfsS*t&g!zw}C_9u(_ze-vc1L59CdBl(IS^yrvsksfvjXfm>(lcol%L3))Q z@ZT;aumO3Q#8R!-)U697NBM@11jQ>lWBPs#?M4_(w=V_73rsiZh8awEm>q1phn1Ks ze@D|zskeome3uilE8-dgG(EojlI(@Yhfm}Xh_AgueHV`SL##I@?VR+bEHH=sh21A_ zhs&pIN7YTLcmJiyf4lZ;`?pN0`8@QbzDpmT`$m0CTrTMiCq%dE&Cd_{-h`I~f8Kps zAuZt4z)}@T>w$9V@iLi=mh({yiCl}}d>JN)z;*G<6&mgl(CYhJHCAPl=PYK2D>*F zy;YK=xS@1JW7i=C)T04(2P#|fowalY=`Y`G8?eRMAKt|ddG9UF^0M5 zW=ZGZ5qb-z@}iS`4RKXvuPIfzUHT)rv<8a|b?bgB3n=ziCiX4m2~CdVBKHWxw2+Hz zLvqoAij9(0moKoo2$`dqS0?5-(?^RXfcsQB6hU2SAgq8wyeasuyFGcK+@An?8ZzVw zW8wwbZB@i=<<4fA7JKPkki6y>>qO3_bW>-uQ*>9g+g7M0U^`RV)YTrGu2Q=2K>fiI zY0dFs>+}xuOZE^efLK2K6&X@>+y10Oqejnnq^NjfXt9JpK4K_E=cl29 z(t2P;kl4AK_Jg9v{1(z)ESpyo_(Z`74D&J1A#J?l5&J^Ad1sm5;Po@s9v7wOs(=_T zkutjt`BaxT09G{-r>yzyKLlM(k`GZl5m+Tgvq=IN|VjtJ*Zu66@#Rw;qdfZqi15A@fr^vz?071F5!T`s>Lx5!TszI%UK|7dDU;rUCwrRcLh!TZZ9$UMfo z@Qzjw>tKS3&-pyWS^p4mMtx`AvwxVc?g?#8aj@jQ#YKDG0aCx{pU+36?ctAiz=f$k z05S(b&VPQgA(Sm`oP&M^eiHvBe&PcTb+j$!!Yx(j3iI5zcQLOn(QqfX5OElbSsQBUw7);5C92onieJyx`p{V!iwXk)+1v zA6vStRZo0hc>m5yz-pkby#9`iG5+qJ{x>6I@qeAK zSBFylj8{FU*0YbFd2FZ6zdt^2p?V;3F~kap`UQgf@}c33+6xP)hK)fmDo@mm=`47* z9S6rnwCSL&aqgZs959!lhEZZp`*>V8ifNmL;cqajMuaJ~t`;jLPB?X~Ylk_Z#Q;%} zV+sAJ=4505-DdnIR=@D_a`Gy#RxtSX+i-zInO@LVDOd*p>M-|X(qRrZ3S(>(=Oj>} z89d75&n?m^j>;SOXM=)vNoum|3YmzxjYx%^AU*V|5v@SjBYtESp^yz?eQ#>5pnCj} zJ_WCw23wGd2AA-iBve8Hq8`%B3K4@9q@a}sf$49IA^IPsX@QK)36mrzqOv?R_n9K@ zw3=^_m#j{gNR0;&+F~wlS(i8IQN8mIvIO)mkx|e)u*y+xDie}%mkZ*m)BQM^$R@-g z1FrP0{8A?EcxtxxxX&J;393ljwwG?2A2?y-1M0-tw$?5ssoEsbPi?sd2!s~TrwPLF zYo-5XYV7AU-c|Vb-v;>pVi^CwX(Rpt<9{Ic?@<9SrNu>F(gwij%?dC9^!Xo90o1-| z&_aPKo%+xyw64e&v<}F^-7sO0Cz-VOF@7**i@v&(Oy4Q8PbV+4&rKwmYyokM z48OZ|^%*mC_Q)RJ31D#b4o4Jzr{~BX4D#swW<31;qCil2qlim;e=9ymJAEXfv-|h3 z)>uqQ5~S+8IgiWW28Fqbq+@ukCLy+k7eGa1i5#G_tAUquw$FjFvQt6~kWa69KXvAj z-knF`5yWMEJvCbTX!K{L)VeNF?(+s?eNjtE5ivg^-#937-l()2nKr#cHShB&Pl^l8 zVYws26D^7nXPlm<_DYU{iDS>6Bq0@QsN%6n>XHVvP<^rDWscC!c+LFrK#)T@$%_0{ zob%f&oaq>1_Z8Ata@Y2K6n?GYg|l8SgUr(}hi4D!@KL~hjRv<}ZZ`tCD^ev=H&^0pP%6q2e+t=Ua`ag8xqWvNnIvCU|6ZA^L5v{DD)!mcQ@n6{=; z#Z)PrAz>*+h-|IV!&J*f@{xb!L7h3{?FEs*ifw5z2U9$&OkYseI68yb=V4xv*VK3- zVxGhtmedujX32y-kC{5ej-Wy#JvB~4oxTb{|1H825_B(A0#?CjUTc=PrGh6jAgK9h zoLAe`+NBdStZE@Y8UH^Rd*|R-|7Ke}wr$(CZQHhO+upHlCp)%n+fH_}S8%^%xqhu%20_1p=x#Dl9ia`c3iM+9Vh5?gyY8M9c$tJ5>}V_sidHN zoMl%rSgSK!7+Y8tQkYq|;Vh`4by2uMsUfnxkk2{S@a>V#d}fv}Yud*>paVi_~T zU!GoYwWbnG%92!Cte(zhZX-i9#KJ;b{$(aZs|{MerP#6||UUx$=y)4XOb zihyKn`_QhJ#~@_peJ*8yD4>I7wQyKkZG%#FTKZfb(@G+9x7-3@hG}+ZC&$7DwbaB$ zC)jLj7yituY&WpOWlG7Z4Tuxzdwo6k!3lgwhh7BYMyB? zO9Q5nvn77~g~c623b`Pe5efNzYD#2Sfmg>aMB5s?4NC|-0pIXy%%`J;+E{(irb!Szc8M8A@!}0zqJLoG4SJ5$~1*yRo0^Z`uObA+= zV?1sYNvzvWbP%AsMzoIo3Cwx~y%i8rHF(BgLS>tH5Ab|1wp$X_3o2_VB(pFxgQ5QQ zk@)Vy95$b%HVf4@ppX(wrv^Jwfrsu+9N_OUm}nD7Ch_7STj66EYsZR#`9k|Tf^@p& ziHwnO$p{TB#R(Q{Os>Un~0!r$JO zLZ&F%SP|%$TuG)mFeOhKr1?S!aa0jTV$2XIeZb_fgO&n{8HTe9s`L&(tKoy?OaS^$ zLHNrgYgq920EI~M>LyU7gK70$7*`nFKD^d>MoEAhsBU0%@*RW@%T(J z?+wVbz=mcN%4#7qlCpl_^Ay7VB%?+uW1WSNnQOj^tALyqTpV zkEN2C;qO_W)MYl^Ow5I;t3;z#iG82F(qe}#QeE;AjA=wM==dB(Gu+ez*5|RVxO4}l zt`o?*B;);-0`vR(#+Q^L4WH_9wklh-S-L-_zd%Q0LZ%|H5=>Z)-x#Z+m%p&6$2ScV zEBneIGo)r0oT)xjze*Q~AIqhB%lOM5Id}^eKwS!?b_;B&TouZsemyL&y`)#FX}ZKp zp)ZnB*^)1P@2bCoe+Z|#KhTBNrT)UN@WIuudw})fwHl)re1|b~E1F=xpH?7L77p>5 zei$aD@KO0<+zo1<&7OuZatNsPq24Whu%0jD_ z$ZZy6MzayYgTJulNEy8D$F%JDYgx|d6{6kpDg#s170<15bM#4tzvrDU$6bvu-hH@6 zgcjq&3aR3k(23$FaUA|iuoy*bO{2F6W0<+ZdsYvXjc?d@ZT8kM!GD}r@qr;TF@0Hb z2Dz-A!HZ$-qJ?F%w6_`t`8xk$f$MNBfjqwvJiVdD+pf7NVFGh?O=qp2vh%UcYvc{rFldib~rkIlo`seU%pO_6hmBWGMcUhsBSWiQYYPMX<-Cjp49@7U==iS57bG zw3T9Nbm`)m9<<4e$U74`t~zRo0JSfi}=GdQXGLLPyW zlT^I}y=t$j{Vx!wN^z8X4l0|@RNrC#)G>bK)7IT7Qop>YdS^NnI3gfP>vtp)pXkr2WSVcAAv8uN>@ z`6)kICvNYU$DA8pnkl4sQopDC6<_M8zGJ^@ANXJL(yd#n1XFj9pH;rld*gwY8om_I zdB55w@FUQ_2k}d%HtQsmUx_7Mzftky&o2X2yDQrgGcehmrDDDtUJj5``AX$gzEbMc zUj2Qzp)Lo>y-O*@HJ|g9$GR2-jgjKfB68J6OlIg;4F2@2?FlW zqj|lO7A2Ts-Kd!SO|r9XLbPt_B~pBpF40xcr0h=a&$bg(cwjp>v%d~Uk-7GUWom?1 z92p+C0~)Og*-N~daT#gQdG{&dPRZso(#{jGeDb1G`N)^nFSB`{2-UQ&!fkPyK`m03 z_Di94`{-(%3nE4}7;4MZ)Pmawf#{}lyTSs5f(r;r1Dp4<;27K=F}Oga^VsUs3*NIn zOsYstpqpRF&rq^9>m50LRORj>=;{CV2&#C$-{M5{oY9biBSoQyXvugVcwyT-19S;pf!`GSNqb4**TI%Y z*zyV)XN3Fdp3RNNr9FU+cV*tt?4L8>D@kJp^rkf_rJ~DPYL}oJngd1^l!4ITQN`0RTT^iq4xMg|S6;d}lznE$Ip^8pW-CHu zP*^!U>Lcd3*shqa)pswq;y<|ISM1g1RG#`|MSPNAsw*XH1IAD(e(Kgqp6aDHgv>fI z!P67$z{#()Pdo3;4dUoy*Xor(O?+YTRPe=g*FfRj*9q9!8p%1l>g3e^rQ_nm{(@4t z?^nMDC2J8@my5q0QyCljCSp_@)No+6bZ*y)lSdrkLFcR6YOHu*vZ-q(C);5$MmM_z z1WT>Gc8g%`Rt~6*!}JhWi0=Rc_z5c8GR9YXW+cdoK~Ea(@wyXf|89HagNuFAO-V7k zUb|9zaCCWH3^Fz(m7$8K$|0ZOP!SNpgP!ql<)!z8w$Z$?9gq2f<~koe3|zD=imLfD z>IV5?SkRZ;7JlOG%z%Tlze$GXr0A}ResyF63ZGZVDLv2k4HWtoqoCaq+Z&GaVKuLA z>@zhNjYYc=sexH?;DTe4&2vnQE}C@UFo&|qcLddvH0FwswdRUc(p*X&IT^Zu>xLpG zn(@C%3ig(l2ZPm#Fc){+0b+%O7nt4zbOt+3@GQVm|1t70=-U(>yo3VY2`FnXFHUyi zwiqf(akt0kEE5_Pa-a*VCS}Pi6?`~P%bvX6UT~r-tUAY%I4XF3^nC+tf3alyL{M`w zv?aVQ#usdwpZmkrfv19O39}tQPQM+oY**a{X?@3Qe>r$+G!>r#?Id&U&m^HU(f= zjVpSi9M||1FyNQA&PO`*94&(qTTMQv3-z`bpCXs-3bX}#Ovqec<>omYhB*VrwxqjY zF3#OXFsj`h#G?F}UAilxTQ|78-edHc-Uc-LHaH*Y(K%R#dVw>_gz}kRD4s#+U&Pq= zps)kMf_t9`GHR7CO4zI8WVj0%qiSqy50N{e_5o#GrvNhMpJf5_sCPrEa%a@ltFnss ziaWh26vEW4fQp}qa4oP(l4xIMpA)~VHD9!lP%;Tm`(HD$jYMM-5Ag>S(gC35J35$%?^gk(r|`4Ewi-W z;f&;B*fO=kC@N=r<-#nGW|yXE;`zb0Y3TJOAkw1a$SQgoTawHZTck+V%T=spmP`^BHihc(jc+S1ObX%6AYQ6LVVc+BfM*P{2s0T2z zVIs*5{ql%#CKAzv0?@S+%||z;`dpfj0Y(VtA51n$j%sG5I%A|h98VU}PkVZFrk1*G zaw75v3(N50lanvr&ND4=7Db;HS4fpi)2vTME7aD2-8N5+kcOXmYCrLE?*5&dWhvB` zbD5)ADuIwwpS*Ms;1qyns(8&tZ*)0*&_lNa`_(phwqkL}h#WdX_ zyKg%+7vP>*&Fus9E4SqIN*Ms`QLB(YOnJ|md%U|X`r#tVN$#q6nEH1|blQ?9e(3|3 z`i#;GUl~v?I6&I6%YvkvmR?*l%&z)Pv8irzVQsWrZSr%aoYuPJa#EjK|4NmiuswK= zlKP2v&;yXv3>LQ$P){aYWrb)5GICwbj;ygw>*amKP;Z{xb^cF}O@IeQ^hB-OjEK{l z>#PNyLuVkeDroL9SK2*ChHmJJSkv@YRn7)E49fy!3tqhq`HtHs_(DK|2Lyv(%9L&f zSy+H}Uk{nE2^5h7zN7;{tP3)$1GK9Xcv^L48Sodg0}ZST@}x607yJo2O*XCfs7*wT@d?G^Q6QQRb!kVn?}iZLUVoyh8M4A^ElaHD*Nn2= zkfCS=(Bg9-Mck6K{ z%ZM59Rs4(j1tSG1B#wS=$kQfXSvw6V>A(IC@>F;5RrCos`N{>Oyg|o*qR2EJ>5Gpe ze~a4CB{mmDXC7C>uS@VL&t%X#&4k<`nDx;Zjmo%?A4fV3KOhBr;VuO!cvM8s2;pG5 zcAs!j?nshFQhNA`G3HMS z?8bfRyy1LwSYktu+I7Hurb-AIU9r|rl5nMd!S&!()6xYNJ1EqJd9BkjgDH@F*! zzjtj4ezywvlkV7X@dG^oOB}T76eK=y!YZB#53LhYsZuP&HdmVL>6kH8&xwa zxv8;t-AE>D5K<{`-({E0O4%fGiLVI8#GfZ0aXR6SfYiPUJKnujMoTI5El<1ZO9w|u zS3lJFx<7XUoUD(@)$pDcs3taMb*(v2yj#G)=Mz-1M1q@Tf4o{s9}Uj9Yo?8refJwV zJ;b+7kf0M}fluzHHHS!Ph8MGJxJNks7C$58^EmlaJcp`5nx+O7?J)4}1!Y>-GHf9o zk}oTyPa>+YC$)(Qm8|MhEWbj?XEq}R=0NFH@F3ymW>&KS!e&k5*05>V@O*~my_Th; zlP05~S5@q+XG>0EuSH!~gZe_@5Dbj}oNIiPJpEOip+3l!gyze@%qOkmjmx=?FWJLF zj?b}f8Vet*yYd16KmM43rVfZo?rz3u|L6Foi*GQe4+{REUv9*}d?%a{%=8|i;I!aT z7Wxm}QJC`?cEt9+$@kSkB!@`TKZz1|yrA1^*7geq zD5Kx-zf|pvWA+8s$egLrb=kY385v2WCGL{y4I15NCz5NMnyXP_^@rsP#LN$%`2+AL zJaUyV<5;B^7f+pLzTN50Z~6KC0WI<|#bMfv+JiP3RTN^2!a7*oi+@v3w*sm5#|7zz zosF*{&;fHBXn2@uguQ1IDsh(oJzH#i4%pk;Qh^T zfQLyOW;E*NqU!Fki*f-T4j(?C$lY2CT{e!uW}8E(evb3!S%>v^NtNy@BTYAD;DkVo zn9ehVGaO7s?PQBP{p%b#orGi6Y&~<;D%XLWdUi}`Nu-(U$wBBTt*|N4##sm2JSuWc)TRoYg57cM*VDGj~ka<=&JF zo8=4>Z8F`wA?AUHtoi$_hHoK!3v?l*P0$g^yipOWlcex4?N2?Ewb1U=lu}0`QICA4 zef61j-^1p}hkA*0_(esa!p%dX6%-1e-eMfQsIp6wRgtE=6=hDe`&jel{y=6x5;78s z?5^{J|t!#x1aS8<3C`v%E%u{*wZwSXr$0Owl5_ zmXh>D>C_SjOCL^CyGZpBpM5`eymt{*rf~9`%F&&o7*S!H%3X)7~QFgn^J>6 zD+yV}u{HN-x9*_$R;a+k?4k*1f)rE~K|QvcC3dlr>!nftB?gE-cfcPMj&9mRl>|Lg zQyCe|&SuZopU0>IfRmcV3^_mhueN5oQ=J+H4%UsSIum4r4!`^DJqZr?1j3BU)Ttzg z6LwM)W&UEMIe*H2T6|{rQ;x9qGbp7ca#-!Egm4|ECNTMN);`>2Q&%|BpOdIJ4l|fp zk!qEhl;n(Y7~R1YNt7FnY10bQZXRna2X`E_D1f*}v1bW^lJorDD0_p2Rkr32n}hY! zCDB(t$)4YOd)97R60gfg3|wrlsVs#4=poh4JS7Ykg$H)vE#B|YFrxU-$Ae^~62e;! zK9mwxK?dV4(|0_sv(zY&mzkf{x@!T8@}Z6Bf)#sfGy#XyRS1{$Bl(6&+db=>uy-@y z$Eq~9fYX$06>PSKAs#|7RqJ3GFb;@(^e`jpo-14%^{|%}&|6h{CD(w@8(bu-m=dVl zoWmYtxTjwKlI!^nwJ}^+ql`&fE#pcj*3I|_Z>#y##e@AvnlSN4po#4N#}WT)V5oNP zkG+h_Yb=fB$)i`e2Fd28kS$;$*_sI;o0Xoj#uVAtsB6CjX&|;Bk}HzQ*hJ!HDQ&qZ z^qf{}c`l^h5sg-i(pEg#_9aW(yTi?#WH=48?2Hfl_X+(SfW)_c48bG5Bf+MDNp>Y#Mpil%{IzCXD&azAq4&1U10=$#ETJzev$)C*S;Pr9papU3OabRQk_toRZ!Ge(4-=Ki8Db?eSBq~ZT#ufL6SKaXZ+9rA~ zQwyTQTI7*NXOhn?^$QOU>Y6PyCFP|pg;wi8VZ5Z$)7+(I_9cy--(;T#c9SO;Hk~|_ z0tEQ)?geu8C(E$>e1wy%f@o;Ar2e#3HZP$I#+9ar9bDa(RUOA+y!oB;NEBQ`VMb@_ zLFj{syU4mN%9GF;zCwNbx@^)jkv$|vFtbtbi7_odG)9s=q(-PtOnIVcwy(FxnEZm&O^y`vwRfhB z7Urcums9SQS6(swAgl?S|WDGUTFQu51yG$8069U zviuZ=@J&7tQ8DZG<(a->RzV+sUrmH$WG+QvZmUJhT*IoR3#3{ugW%XG0s?_ycS6V6 zS)019<_Rl@DN~8K4#w3g_lvRm4mK3&jmI$mwROr0>D`mX+228Dw4r;mvx7df zy~$zP8NjVX?xkGFaV>|BLuXMQ+BN+MMrIB4S6X)p&5l$;6=S8oI9qi&1iQbs?TroDMfCmIeJ}pbVVtVqHhS(zutEy6#UjTk29-+3@W0`KfehW`@np zhhu#)O&g%r)hTj4b$CY41NYp_)7!bYyG;v(rts z^}YDJt2W88H^H;e$LSm3dh=~yi@)mzJtEfW8=4avbeOE&;Oc>-6OHO+MW`XBZ4rO6 zS;nAi**w3Yso4&Ty+8f$uvT?Z)eaLe$KW1I~9YM2zeTIT}C%_G6FPH-s5Wi3r`=I&juGTfl zZ;4qFZV|6V0c&>t!Y>mvGx#1WWL0N5evV=u28K9**dv`}U3tJ$W?>3InXiwyc)SA% zcnH}(zb0@&wmE>J07n#DOs7~lw>5qUY0(JDQszC~KAAM}Bmd-2tGIzUpO@|yGBrJyXGJk3d+7 zJBN0$?Se(rEb0-z2m%CBd;~_4aH04%9UnSc4KP!FDAM5F_EFujJZ!KDR-fn181GX` z8A?8BUYV}D9bCE0eV~M>9SPag%iVCLWOYQJDzC4~B~Ct0{H7x|kOmVcTQ;esvyHJC zi$H0R73Z8+Z!9^3|2tNut#&MVKbm`8?65s)UM8rg6uE(|e^DYqvoc15-f;u8c=>3;Viz*T# zN%!T+Hex0>>_gUKs%+lgY9jo6CnxL6qnQ>C*RseLWRpipqI;AQE7;LUwL`zM%b`Vu z%Sa-+?a#+=)HaD|k2%_(b;pHRF96(c;QyPl6XHL8IqGQKC$M8R=US-c8;hUe?LKo&l!{V)8d&55sUXEu z5uITcO~`ipddh+Nr{7ibp^Wd{bU)^3##<5`lkuqfckxEU*9{pgNpTB2=ku1c-|3dK z|LIQF=ld@I7swq^4|G1VA}BK85&>2p#*P95W`I1FF(8G9vfNJ6MoN$+C^M89u!X=< zJSS%l?Qj>$J%9?0#0&S6#*h*(-9Z$}q*G#hP?cX7cAvM0eiVFhJJ~$`iZM!N5NhDb zi<1u_m#?jzpIaOe7h|Kiap#mHA`L|)ATnPJ7du{^ybuNx@1jA+V1l8ux#{LJ#teM(6=%gZcMq24J$2p z`wcC!qRssmwUv4H6Psw{(YdDNOv$!sq&O1SvIS}fCKZa+`T=Ayt@uZjQqEC{@Uj+| z!;i3W+p~=@fqEEhW@gT^JtCR<`m`i|Htg<TSJ&v`p;55ed zt@a|)70mq;#RP@=%76*iz>fAr7FKd|X8*@?9sWOFf$gbH$XFG zcUNu#=_+ovUd>FW*twO`+NSo*bcea=nbQ_gu^C7iR*dZtYbMkXL5mB@4a3@0wnwH! z(fZKLy+yfQRd%}-!aPC z4GB%OvPHXl(^H(BwVr6u6s=I;`SHQ1um7GPCdP-BjO%OQUH!_UKbEGvHCY}{OL`8FU$GZ;Y$SlS$-0VjK%lCP?U0shcadt4x7lN4%V}wBrLEbiEcK-OHl+pcBNSqN#mftpRj2A4Q z+av@-<#t_Dj_FN^O2~wq(ij1O*+=RVl+6gNV^~CI1UED- zn^zN@UOq8?q58b^4RA>lV}x;jA2OE=SqMYV9P#RsUlI+pp!y*jpwHgp-w3i$V)%?L z>irn1pnRc|P@r|Z0pCeMZ*k$}$`1GVGCT&QtJ`V%Mq!TXoge?8Fjn$bz}NqDn*2ZQ z$p3@F_^(}IVS76>OLNzs`O5!pF=LZ$<&gyuM$HQzHx8ww^FVxnP%Yv2i=m*1ASF~~ zP=!H}b`xl`k0pL5byku2QOS~!_1po!6vQyQL#LQ#rIRr?G5^W?yuNvw-PP{}%m35i$i+I?DJ%RGRcqekT#X~CxOjkV1UQrd&m_bbJ+gsSGbPwKS{F& zU-`QNw!*yq#Co#{)2JvP-6>lY$J$2u+e=r0&kEc#j#jh@4Tp;l*s<28wU%r= zezVPG^r*a?&Fn_(M|A7^xTPD998E-)-A4agNwT?=>FbrHz8w~w?hWBeHVYM()|buJ zvGv4j<%!U_Rh^ZKi~2(h1vk-?o9;`*Zc}m5#o@a1ncp)}rO2SDD9y!nT$_Eb%h`>% zDmssJ8Dl=gDn<-7Ug$~nTaRzd?CJh;?}nCco$7Pz<#J8;YL40#VFbAG|4nA$co;l^byBOT2Ki@gAO!{xU7-TY|rujdYTaWV(Rr{Jwu?(_TA zDR1|~ExJBfJ?MAReMF47u!oEw>JHVREmROknZUs2>yaboEyVs$Pg1f6vs06gCQp$b z?##4PWI#BxjCAVl>46V_dm4?uw=Y@h#}ER4|ACU{lddiweg`vq>gmB25`XuhNai1- zjt{?&%;TRFE+2Y_Gn;p^&&|bU44M=`9!Mc%NbHv|2E4!2+dUL z>6be$Kh|Duz}+)(R7WXsh!m`+#t^Its($x`pqDaN-^E z?*a=0Ck^rZBLQV~jY-SBliN&7%-y3s@FB;X)z(t&D=~@U0vT%xfcu`Lix=W#WVE{{ z2=C~L$>`~@JCIg8RAyk= zYG`(@w4H95n0@Fqv16~nlDU!+QZw&#w@K)hv!V>zA!ZOL$1Iykd&Su3rEln@(gxO| zxWc++T-rQEIL+j7i`TeatMfp4z7Ir31(TE4+_Ds@M|-+cwQg(z>s=S}gsSz{X*Wm+ ziKJWgOd`5^o|5a#i%?Gvw~8e?Rpi7C>nQ5dvPHVTO$PI^mnJ*7?gd3RD{|c_a>WrXT#Es3d}(k z$wpmA#$Q^zFclx{-GUL_M$i0&mRQMd4J#xq-5es)yD{kYCP1s!An(~K5JDRkv6DUSKgo^s@lVM5|V4mWjNZp zsuw^##l%rbRDKglQyj?YT!nk$lNUzh%kH705HWhiMuv(5a<~yoRDM&oCqm+1#S~|8 zA$g2Xr=}p_FX%Eaq{tUO9i*Q1i!>$+1JYZCL}flWRvF0y1=#D#y-JQTwx6uP-(bC} z_uP7)c;Xd`C6k#JVW?#Id7-|`uW+hN0>OM=C2Ta^4?G zr;EvxJ{%l|8D-heRYRM%f*LBC)krHZJ@%&CL0)FADWh14&7KV<9km6gE=o9(7keg~^rIQtthK^_8%Jk&aZLY_bc6SbY>IcwDK9{sV*t1GfKwf8aCo8t za)yALEi^-WXb!k6n>W-62Z^n8hO|eRYr&uZiW5d_URi??nl*aGu?ioQ+9RF9u8kwD z6UZ6HVd(G%l9>y7E)uyn?gAJMKeki0@tG*jdcE-}K?8(D-&n=Ld1i=A1AI<1z>u5p=B z<1}|q3@2jNxW-}Q4z~s|j&^Qc;nXIdS3K8caP_07#ig} z#KAD&ue2jXc&K#Q`Hy#x+LeT4HHUCzi1e?*3w{tK+5Tij(#2l2%p#YGI-b~{5{aS8 z!jABC*n6y~W|h;P!kn(a4$Ri2G118!?0WHDNn((QDJP^I{{wPf<^efQWW?zS>VS?X zfIUgCS{7oV$|7z2hJBt+pp1CPx4L{B_yC3oWdE)d)20WG6m5qknl}8@;kjPJE@!xP zV(Nkv^-Vz>DuwBXmKT(z>57*D<$u=Blt)IS-RK0j89omD{5Ya*ULWkoO)qeM_*)jF zIn87l{kXPp=}4ufM1h7t(lAL?-kEq>_DE-in8-!@+>E1+gCV9Fq)5V3SY?**;AKq0 zIpQ(1u*3MVh#tHRu5E5=B{W-QOI34plm`#uH(mk*;9&Re%?|v-=fvb;?qvVL@gc|l z8^L?2_0ZrVFS-stRY(E>UiQeG_sMrw5UiO znGFLOP-GO{JtBM@!)Q37k3G_p&JhdwPwtJS6@R4_($Ut^b!8HP{52-tkue8MG=Zwr z7u6WaFranJq4oNadY)>_6d~?pKVxg$2Uz`zZPnZVHOh-;M|H7qbV0OF8}z;ZPoI+| z(`e}bn6u*kJpRLC>OZ}gX#eHCMEk#d8y$XzSU;QZ|An$pQ%uZC$=Ki!h@&m8$5(xCtGaY3X1FsU?l5w^Fr{Q-?+EbUBxx+b?D z80o*@qg0juG;aZhj=tO=YHjfo=1+-NqLME~Kw7Y1A*?}M7#cOyT(vd$1tVPKKd@U! z&oV!RzZcK6gPWj`*8FIAy2I&x``h_sXPe*O{|ih(Y+V3|o68MWq~2Iy^iQ8RqK76f zC$1+hXqd^jsz`U{+EFo^VQNrLZt#R`qE*>2-Ip&(@6FmtAngx@+YnG}b5B9Y)^wg#oc z24KlT2s!H_4ZR^1_nDX#UH4(UTgl603&Q3g{G4!?6Sl9Om=Sy|8CjWO>d@e9?Q%s- z-OS3*W_H7*LW|Ne{b+^#LqQ}UKDmiZDma@no2!ydO^jcm>+z379K%=Ifs{20mT|xh zP$e7P=?N(tW4PMHJOQ`a8?n}>^&@<`1Rgo`aRevPp^1n7ibeS6sc8^GPe>c&{Kc+R z^2_F~K=HVI45Pf|<3)^;I{?H}vU7-QK3L1nHpcn3!1_)<$V;e0d_b8^d1T==rVpky zZTn~UvKrjdr11k}UO@o>aR2wn{jX5`KQQM1J1A?^wAFvi&A#NA#`_qKksu`sQ0tdM ziif17TO<{wDq_Q;OM}+1xMji^5X=syK=$QdZnS#dwe$;JYC7JozV8KpwfV}?As|^! zFlln0UitprIpuzLd$`<{_XoUV>rrHgc{cUQH-Px#(_Ul%=#ENrfJe@MRP_$E@FLMa zI`(J)Imw$o427@Oc^3(U&vz}<3Lfmy7diVpJJJ@gA>e;q-&gj zcGcBC_luF%_;**EB?o--G?AkaruJ%-b*8aX$4E+-?V@RWMnjHJ;hx27Vd7l0nUUY( z6OQb&8g8cvN3LZ%^xvIav*X|Epqm@yrTZk9U{GSZXAUJt8Lh(%7?Eaf&AzmXOVvU| zmz<@l1oMe#^POR38KT6q3@c`{%eYNu4ccurv`q?b5DzLxENjSfYOJHAI$MbSNgB*D zJsP>i*BgrFlIn?x&DH9x~UbPBtMFj{_vJ#CaAF>1$oE&k`EF&L@HCa@mN>Q7~!RU>7 zW%fv84aCKSgBacmuvg}r@)YKqO$U{D5|!`vG-Gp%An}raz2gESWm0Exhux4C)zE}} z_@kn z3t}bvm?L+@@az@<*jG>(Xopq&c*;^mttlJ!mv;5k6o%Ac<_`o`4G3qzzo(GO{!&F8 zW+~bF?S;7gO1dQ@>gwZ?iIHjE#^@;Ix!Z`R6{RYLlGB&v4A)ha(2hc`RGV-8`LcvSf+Y@lhT%(Z7$tWEF;cZs2{B|9k#&C}sPyr; zd-g~${TqY7E$9X+h4_(yMxQ%q;tm(h(lKzK)2FQ%k#b2}aMy+a=LHYgk?1|1VQ=&e z9)olOA5H}UD{%nu+!3^HsrBoX^D9Iy0pw!xNGXB6bPSpKDAaun{!fT~Z~`xp&Ii~k zdac?&*lkM+k_&+4oc6=KJ6RwIkB|st@DiQ!4`sI;@40>%zAG^!oG2@ z@eBM$2PJ@F&_3_}oc8A*7mp-0bWng^he9UYX#Ph*JL+<>y+moP^xvQF!MD_)h@b}c2GVX8Ez`x!kjAIV>y9h;2EgwMhDc~tn<2~`lf9j8-Q~yL zM=!Ahm|3JL3?@Tt(OuDDfljlbbN@nIgn#k+7VC+Ko;@iKi>~ovA)(M6rz5KP(yiH| z#iwJqOB7VmFZ#6qI~93C`&qTxT(*Q@om-Xb%ntm_?E;|58Ipd1F!r>^vEjy}*M^E(WslbfLE z<+71#sY~m$gZvoRX@=^FY}X?5qoU|Vg8(o`Om5RM6I(baU^6HmB<+n9rBl@N$CmP41^s?s1ey}wu3r3 z4~1dkyi%kA#*pLQy0phlXa-u(oK2Dwzhuex$YZv=*t*Tg5=n~H=}fJA!p2L78y3D2 zimkqC1gTU(0q||k9QM#><$b-Ilw#Ut2>JF=T^qN34^qcBEd={! zB)rxUbM2IwvMo?S;Id^aglw}-t9et}@TP;!QlFoqqcs(-HfNt9VqGFJ4*Ko*Kk#*B zGpJ>tA9(=t|4#M!kBaf%{$Kfj3-uf|ZFgiU`Bo>%k_OuAp~vnE^_Tg8*% z*?)4JdzyMTzvNDy{r$c``zBw=Vr)6c4}CBIv#mw()3h7`?V-;LF?J&N5a>kjpy;9n zQyXvuu`n?+W84QV=(i`JEJY=}Ak+u4>!Lyt2P!$nBl}T=^|pG*z@)_l!)OKB{tIV&&E@hj=OIhSBHgPV~X=R3NrTMh?VzDm?1yW^IJ&zzAn2{8rE~MRX5EE)a(-T&oE)1J4pGXBYi+nexX-?5! z{EZ4Ju=Y8MQ87=uNc2t^7@X)?85KeSoc`?BmCD;Uv_cwQaLyc}vvnJKHV zuK)H_d)xhGKB!_pRXv{$XgfZ_(8G%N3o$ZI#_ zixQj~so0*m^iuA!bT>&8R@>b%#B~zbIlwt4Ba0v&>B(`*Z;~?6!>-aQ zal+Qt4^dCcjZZMd4b4Khg~(GP#8$3BeB8j!-6l?*##)H?J$PeUy)cA_I26#0aggao zaM5PweS_Sb@{OZ@Uw*(!DNV)KTQU+BTRi?AUAv0Vowth`7mr9)ZVC+TI?@; zWGL&zydnsuE3+D7#U~P%PrxpD3nTc9#mm621iX*?ZMS_Q#n9SzOJ~Hg@`rX{d?qJ; zt}`76!H)MX#=VKifJZP$3<8@}0-llthFpq3FV;(UP$-k63MkHHq~J&}d?C<+c~*Zk z<#G&>AD7EoiAVO38TO2TOBKN>6N|JS*{+`}V-)T0j(bAzGlEUWEvWLrMOIItYexh) z?he>SJk*#bywgDF6+*&%>n%0`-3tOY72+n&Q1NJ`A-bX*2tJV(@;%b6&RxMcUd7+# z@UzOmc9DolSHc-D$5(GouinaE%&uOVMyD&CTdKaEB{Qap4_wU7_=23CULKQ;jmZuV;+Y$(`#Gh0@}s7-!qk-^&#IG>7B{yft?UoA)H5 z|B0u3Tu0TF{AB0jpT|E&RsYB$3WiQU^5p*|f)^Si_#^j+Ao^|5(gNjn+!0|NtXDt* z5fwxpajl@e0FrdEuj2s#Pg>gUvJdko9RBwEe_4@?aEM?SiA2nvm^tsLML{-AvBWM7 z_bm7%tu*MaJkUWd#?GWVrqaQ0>B%Azkxj+Yidvc$XdG1{@$U~uF|1oovneldx`h;9 zB1>H;;n1_5(h`2ECl?bu-sSY@d!QTa`3DrNj_F@vUIdW5{R7$|K{fN11_l7={h7@D z4}I;wCCq>QR6(;JbVbb4$=OBO)#zVu|0iK~SnW~{SrOq&j*_>YRzU&bHUhPPwiy($ zK0qin8U;#F@@}_P_flw`bW_v^G;ct?Pb65%=%egDBgS#YF3?E36$9xzdvYqjAZoK#hcjctJu~MF^S*$q3`o2;!L|jPnM1x*Q~qF%BH(5UDFYglsJwO zEdEuB7NihnTXK6$)F~``nmSQNFP7x7hE{WuOjTAhEjGw#XxvL@S;aZYuyu9)!yZ~X zo35D6Cwb8`shRXCCR;xlR`n`cs4aie!SSM`0)x3ykwM*k zK~w^4x2u#=jEEi`3Q9AU!wE)Zpn#)0!*~)(T^SEjIJveav(d1$RaSMC0|}<)?}nSG zRC2xEBN_YAsuKyl_3yDt%W^F`J-TyeGrcfboC_0Ta=KcW_?~RLb>xbqIVI6`%iWz; zM8Kq9QzwO8w!TntqcB;gNuV$gd+N|(4?6A9GEzYs z5f4(*N5}&ObeYA~I28r;?pKUj4N6}iloE=ok%1|X()Ahdwir?xf6QJfY7owe>pPj)Me*}c^%W-pP6`dnX1&6 z`b#*_P0PeM+1FR)t)Rnr22f!@UFBW!TxgjV)u0%_C~gIbb_D3aPhZ~Wmex0)Lj`VoZKjoW)dUoKY6*| z0|V)|XyjiKgZ}s5(SN?te*muif87vD_(wYOiOjOKNI4L*aK||2$~;s25HS#iY6r=)WW8a^dkd0Y|pPc1-9jmy&wqoCbL84`C94At6$lm_o!8m*did^?o$m?ozIp{RmZ*M%YMX_i$KYkz_Q)QK?Fdm)REqf*f=@>C-SnW{Lb;yYfk&2nAC~b}&B@@^fY7g;n(FVh_hy zW}ifIO9T7nSBHBQP5%-&GF8@A-!%wJAjDn{gAg=lV6IJv!|-QEXT+O>3yoZNCSD3V zG$B?5Xl20xQT?c%cCh?mParFHBsMGB=_5hl#!$W@JHM-vKkiwYqr8kZJ06n%w|-bS zE?p&12hR2B+YB$0GQd;40fJd6#37-qd1}xc1mNCeC%PDxb zlK=X|WE*qn2fROb4{oXtJZSyjOFleI3i8RBZ?2u?EEL1W-~L%7<`H6Vp0;cz5vv`7jlTXf-7XGwp}3|Xl6tNaII3GC z9y1w*@jFLl2iFA!<5AQ~e@S|uK4WL9<$R^??V^aM?Bgy=#|wl$D2P$o;06>{f)P+X z91};NrzVV+)b}k2#rYLF0X0-A+eRul=opDju)g0+vd79B%i!Y}*&a^L$_|C&jQN^j z9q#4<(4)3qNst^+ZYpyVF2hP;DN|OMxM9w(+)%kFQRcYVI zO-frej9x6a%-D%Xuwedcw9#3VSVkOjNF!BYRoY1KD3wFJ%?ML*3QwcarMK)@v`o%s z$w=NLrO>og`nRJpZZ(%~*hNJU#Y~k;_Ci3~gc=4UQO!Ydje^?=W^DgCKyO;Zz4LgQ zKtm($MdY;UZ((U_g5*pMY+dYGyyT1ERkaj`U#S-2yyJ47wMonCpV+2rI8zPNHDfo& zc59dFz*2#^A-R?P6Np}jhDLi4&vP%$NW#8J>=CLj1mlf$XzmQezH*F1jNOiPgXl2j zzD07AKLT*h$CA*OsOba2etPLU%|p?=XhplXo?vOu@q0{QBo++)@6U?YKv_)GFK(^Y zm&uFBbrQyzJm;c49O00PIt;|{&ei%VSS%Y3m3#~L#(3%Gso^a4#9AaB$w@vnAvdr6 z%!2#)YS0HFt%o)q6~BelT;?%oUjX%9qQCn#-~+TM(a^s%Y>&aBkL(UY{+?a9@&Q+a;t%c_6u^6_r@>MEAN9ir5q=Yo|R8z4lKYd1sv^LyTozFn$KqaJ>? zoH&+`AX>E03Gv=71+NZK2>!-NasKeCfMp;@5rZ z*m<}q2!$AgKUwWRXTVHs!E>`FcMT|fzJo30W551|6RoE#Q0WPD$fdA>IRD-C=ae&$=Fuzc6q1CNF>b3z_c<9!;))OViz@ zP58XOt`WOQS)r@tD0IiEIo4Umc(5f%J1p{y4F(1&3AzeAP%V)e#}>2%8W9~x^l}S4 zUOc9^;@m{eUDGL={35TN0+kQbN$X~)P>~L?3FD>s;=PIq9f{Xsl)b7D@8JW{!WVi=s?aqGVKrSJB zO-V&R>_|3@u=MEV1AF%!V*;mZS=ZK9u5OVbETOE$9JhOs!YRxgwRS9XMQ0TArkAi< zu1EC{6!O{djvwxWk_cF`2JgB zE{oo?Cyjy5@Et}<6+>vsYWY3T7S-EcO?8lrm&3!318GR}f~VZMy+(GQ#X9yLEXnnX z7)UaEJSIHQtj5?O(ZJQ{0W{^JrD=EqH_h`gxh^HS!~)?S)s<7ox3eeb7lS!XiKNiWDj5!S1ZVr8m*Vm(LX=PFO>N%y7l+73j-eS1>v0g}5&G zp?qu*PR0C>)@9!mP#acrxNj`*gh}21yrvqyhpQQK)U6|hk1wt3`@h^0-$GQCE z^f#SJiU zb@27$QZ^SVuNSI7qoRcwiH6H(ax|Xx!@g__4i%NN5wu0;mM`CSTZjJw96htSu%C7? z#pPQ9o4xEOJ#DT#KRu9mzu!GH0jb{vhP$nkD}v`n1`tnnNls#^_AN-c~PD;MVeGMBhLT0Ce2O2nwYOlg39xtI24v>pzQ zanl2Vr$77%weA<>>iVZQ&*K9_hfmv=tXiu#PVzNA;M@2}l&vaQsh84GX_+hrIfZC= z0Se*ilv-%zoXRHyvAQW9nOI2C$%DlFH1%zP-4r8bEfHjB3;8{WH`gOYt zg+fX)HIleuMKewYtjg+cSVRUIxAD9xCn+MT zs`DA7)Wx;B`ycL8Q&dR8+8mfhK;a^Rw9 zh9tC~qa>%5T{^8THrj^VEl5Do4j4h@nkrBG6+k8CDD~KB=57m@BL-)vXGkKIuVO9v z7t_L5rpY^0y=uu5iNw0v&Ca-zWk>v;fLJ=+SaV&V#C-o^}8 zp&Xp$v?~ccnfR=&5Df)32^d6QJLg*iuF#s|0M4zJF@Hza1p`q|f}~K)q;HC*I1_9t zQ&1jr9-kdUi8)DGxiwdqU|rPxYWDQPWY&SI&Rxkhxobp~C=Y*`d?HD4JW?WjU7dBPeuIE`ABLq95b#lfKS52IB^6KoHmm60$R}TESplQt59#mboJj+Na!P)V{ic@$yQ-&Z za^JU0T+n0Lf2VdusoNr0?g~1DMsY)zdY-63yH!Ii#aWe|;0TO>L7#YlaDrH}xvYXn zh-NYa>O>f_NTTBG=|k0qWH+X?d5@+INsQ}WcI_3z1Z4-%Gj#_{P$0A~cAye`?j0cW z8)hd(V}7rattLUSMvgZ4g96P7n` z^{55A&&29;-P992{yhkGWa3v_Z6iB4a&~NmL)IpC&dsSwe$9jS(4RVJGt=Y!b-O~1 zSCl@wlaba_cA*yt(QvulMcLUuK z>(ys_!{vqKy{%%~d#4ibQ5$yKn6|4Ky0_ngH>x-}h3pHzRt;iqs}KzajS!i!Pqs8c zCP%xI*d=F=6za_0g`{ZO^mAwRk0iwkzKB7D)SaLR0h|ovGF2w9C9g8;f#EtDN*vBP9yl;n=;B2a7#E8(%Bw()z(M$_pu zQ+9uFnlJ!5&$kk^S_+kJ>r9y8MFPpSf9;o8v;ZxsMA!p>eaAIwt5xNiQ|2_ydGkbi zkggG;Xp&I7C8R{>ten^j@MsN#V5JPs1Ezc!74->Nh0a}U){OK@j=OIoY}C7IYYd8-V9 zQ6s?v=Y7(?Y$7=P#Wwub-*0DLqli?I%kT-D^jqK?c2~HEx<2(poRWAUoC}!~6$1=I z*M(IfPmdID8i+5l@=1(+`?i`G_ew=1Y!gF?tFbdgtW2etKLOFoNozkH(i!Qa7(h^| zF`9!VeqQQwM+yO6J`;oWUWq@9l6hP~FiG8-{Pj*T`XI3~s@FfjW2Tl(llpa901$&y`F}K1uZuHEo;=mr+_8d(o z2Be#yWHEN@euC$=VUSB+3A}khJdF$)0r#<5(f3n`kx>ZT8ifaKyX*OhffeHH1?6OM z*-19$j5tMNYQoB)>cGpz@11>J%q4KW`GLNj?uB>LcNg$0G@}XN#Tqf2F5@jv<`|~p zqB^l!%v!g{R_+0GX5z0>3Q~O``%T$NFc==dsPsTj-;{b$XUS0TGoJs2BUA*H;4S?w z|Nigt|F@9hf7QLSo}JPEK#CPgYgTjrdCSChx0yJeRdbXipF(OwV)ZvghYba)5NZxS zm=L8k_7Lb?f8`=vpv(@m%gzsCs9^E$D5Jn+sf}1lep*zz&5V?~qi_@B?-$Vd1ti(rCi*I0}c}slKv@H_+g?#yarVzpYZN zIk21Bz9Z#WOF`JG&TC&C%a*3*`)GJx9I!U8+!#J4}@5rm8*jK%Xg2VLjP-a;H zFydWO;nxOZ&|{yOW;ta$ZU^6*4vFP)idD6M*M0+9buB#hK4z%YTGBdSva?Pvxim2` zF-?QVGuRQ2-1eYzd1Y%}w^`t1S7|{{8=Es#ApC0<;pc$|NJ)IU%WVK+4gnTWA7-t1 z0K{DCESXb}!y_tzrycr^%%|G4T4)`$BC8+qm|n1lS?CO=`V`1T#ykY#5g5$dc$lGt zqGHyw-*Av%C;33nEiU(rU?w^3F46!dEz#cHd3IF<(XCq)>JG?Bi)4v26MQr1A-g5RqhFoPy%^TD3sa|D^9aS>>_2-X2i#? ztVp@ZkyMB;Uo#9s!R!@G#CCaFVaxx*8YYu$kGFk4g3|9t!1nKqOaDBAe;w!(6#w)0 z?{&F2BgctT1=Z;TvjOGL_!}Vlt=kaLA7#W`mv1h%hUg983!wA*K@_r6_cd6o z6LHiCE6qwlt2H&|Ica~%b9C?Z@$dreBNR_!NKcfL)%8kGr7!IVq|^&6PKYK%EhcKu z6+uR*%EOw=rF6Q42Mx|a> z$2XrM*NV2x9ci6|X^eh1UAbJ9Ky!#*Q5w7)#o#%}d!#-^k8To=n8{UU*LmFsS-wRj zi6-p76V6g?If3S&Bj~GW&QI_WtyPY0@u3hjKtqf9`8S!wn{@P&Tc8uu8cf)YmrX7+ zrC+O3V{9}JG6ihA&^2Q7@)Kq)j(Y_oTzsoBUYQDG!}`Ame`bbcr>J-6E%gaBPEDCU zflX#1-)Ih^HJV*lew*N_SdG-4!b2}G8%U&9_V0~Qt?ZS z@H3L&5ybV8X}A@KQADl93H`}0qkNm!jGHkCJUM%r8`mP1nV?Oo%^l;yDnU6IJtbuY z`X2Sf8|r00mB_f)Q0;S{FqS1Yq?otd-BVbw`#@SDd5}n5X4lqdDi1*vtVv8-Zi10q zexCj0eyngrp`UxjEOrdzUt`?%jRlj7zSU-V-%R?y+_w7P7f1ge%t1ozmN+&)%3xQW zT3u@)))(_a<6`lTJd`DIYw>(pkb=PMKvCNEG~zza+LVNqkY^}QoGMVdS0K;gS*A3f z;6Ua!^sSV-try(M^pB6D9dsX}c>$Da#NHucp9vr(fg4pbBR*uPhYq+N>q1X4RSOCl znIQj4=A+y+8{?LQ$3L@(!Yy~~Cu4Sx72*%@dW>eP%Br7=uaynV6Mqa-49A9) z|L&5r=4K5SClwc`!2J|>(#n$4y1>lmR~2Om8q6HkcpK>d(Fk!T^NO?hM4Fc+(5J{` z&K|vrBz;;zWlNO%=a~JkMxMiZa%wYz#G901lw#+2SUaMMHrebb&|1L8tKoGJK*QhJ zU9|WkDy^-4F6U&VYSc3ScHDk@kV^0801#I|-pSK%az5=DwI}gMm)@s2O+-ESTk?QY z;y9gyucaXO(Cc+cd{B>2)euMHFT71$a6DssWU>>oLw4E-7>FC-YgZH1QAbRwmdahD zO4KAeuA^0q&yWS|zLTx%(P4VOqZv-^BO`0OFAXdBNt9>LAXmPALi3b|gt{b?e-$z0 z4n7H$eg6y_zs(c>*4FT!kN*$H`43~1p!g;IZ8-mYbUPTejaLW#BZnAPFES?ApM{TQ zE*TC%O8)apqcX|PrNjIZE-z{q`I(LwIE0kf=PLjExEX>)oIu><<@lt>-Ng9i$Lrk( znGXl|i4dP;Mt^-IbEp7K0e#*c7By@gCo@VQIW$93ujLL`)lMbA9R?C_5u~7^KopaAMj#6&>n-SOWlup_@{4 zcJ?w_!9JKPM=&Bd#IQ37F*x39y!azm$;~IRlkm>bHdABcNwW-TdDKD$pkD{j6A8d* z{vP~|<}bj_Oz#83K$ieRtsA4a@4a5cRjJ}A01{PgxXn3;fx)5ElMEPwDX_mW9)9oB z*;scve~v#HHqUj3KdC$tdV3&0)Whkp-=hKKz{SzD7g0@N!wyv;ZAime7AjB7&)!)5 zp_iVblaf)%agwJqOG2e7WTCM1&khq`{b>fN4n8hOJbvO?Y;60>LIwagLXWC@@0RSR zo%lPo1cUU=g$ahJ8D=;`v~ORUSl(1-&a@yTAC5Y8E892@{P@MM=GXUGpBSXSbSs!N z;L~0D_s7{+^F6c!WW+^yz5~o7eWtsOE}8{hKaFlHgnyBeUJ8Zz2$k7Lrh?NuMU|No zVvsq@57)8zin;&ckR1;*Z%(xH2lBw z`x%N;|H1En8au588bPDxP^$kfpO!bIzz>K=5Jiq9Rg(NGde0g!rKagLa+&yC)jg7y zq}~2IH)N*FJC31qrIH-2;%3^F?=bDD^U2Y;%ftN(v71oY;od+vh!!2z^}GHR$43rg z0In@ki}TglIsMU^O1(SiLK#oiuyw zB>-@z?&uW`ILoPupw0_cs?C|2YoX&87~us+ny%eo{A!3M<-7O7mHUBCgA~{yR!Dc^ zb= z8}s4Ly!GdxEQj7HHr<}iu@%Lu+-bV>EZ6MnB~{v7U59;q<9$h}&0WT;SKRpf2IId ztAjig0@{@!ab z{yVt$e@uJ{3R~8*vfrL03KVF2pS5`oR75rm?1c`@a8e{G$zfx^mA*~d>1x`8#dRm) zFESmEnSSsupfB>h7MipTeE!t>BayDVjH~pu&(FI%bRUpZ*H615?2(_6vNmYwbc^KX4HqSi!&mY9$w zpf%C6vy@O30&3N5#0s_!jDk|6qjb-7wE3YT3DA7q3D`Q&Y*y>XbgE7=g#rPx1hnf8 zTWd{IC!Iysq*vZup5VGrO)UM<3)6raR`rOwk(!ikf3XPp!n|gz0hS*P=VDXAyMW(s zL??-`&IusEuOMrz>m(A1W5Q~>9xJwCExAcMkOBD` zD5BJSadd{0u}%z4r!9qA`FW4;Ka_Qk>FcHxiucGw4L9qhtoge|ag8jbr`7LHSbVQz z6|xUo*^LV1SLxS>?D`m=g{8IC&1YF$e}VRGD#ZOc_15QW%J@FbEj8tE-nGxo4?X02 z@|q#k*G4xMW>q84Xc09pRj@>Hz8t^fMm3n&G;Al6KU*;=W`7Q{$^|=bnZiJ7?(s)@ zB`vW>#zJ{}!8=*|?p(~fcXSanO^j8+q7V!q16*ic!HLRdz0TzNI6}m+=OKd2b8KX< zAcDTj*%~vQlcO+%@H01gjv-1zZaOXVoM*t-+KXTR#NoTf-#{dQAm?GqK6q8Ta zu3xW?t=NE$EfYa#=0HofLn5~c#m-U#Ct_r6~X-pg6k*F zYIP7De52BBwcAnK?O(j?YEs1;q60!-!hTuKzw3T;XcA_w5HvU;tO~}byLA^cggu8i z-IP@pxFjTy&ie28m}j66dm@g78xK7aG{QSR^bAcY+W*xWu;G~I08sf(GK4>K-cbfJ z-%v9DGR77He<291M~=fg>>9&NFQlboP)pC6fT;{>_!lM`A&&HWIMd)Y6e@IL;nvRdBE*Tn({&3{-XJ9helJa{G51Ck}-_Y=5C|fEo z)7fZlsHxN&SY&ZLTdYuBBZnwIh0#VTzmyK>U0|r&SXb&GP0m)1dGV8z(^x6s5yQ-z zEyniK${#U@Y7p@Yxx}E+jA?1@{=|e6UM;iyai=0=aItVvqieogZUq@sio2#9NLW~L z{w@^H!HEGU;>;T0lu{Ad20Hr6u;?-9YHKvkjEc)}wsb4Y-ArRK8`24uBT8N)8m%Ee zYJX21)|e{peL26}VUUKYQ3L@NSe8rEbN#AIo$tjJm-$B|IJU?mu(h$Sq`XNY0@NhY z0?WeMtPwP)sUdk}dWA4qBUV^x>P|is-kPgVe)*WV>dKDL>gOq1 zUYw(nU|N#dw>97A_(c3?VA_zDfF{^A1eE#8Bucd^ON(sv-{tc@&i)Y)3V~o7U~+AA zOwnXB5`WN^z$z<9^@(?LY%7?y5X_C(j1ip-Ug^f7Tt6suI3&a=&~#EJegG4r2^tKz zJoEXCVOc1QdOSNHp2d;t&smxL%CfK@mSl)Ky}`!6kCsi#7s5&G2Q!sM9S6o)&mdx% zz|2M~pav2;Th=DTN5yB@6HFAO!pl-y+tEJsh}(? z!tIyg01O*w@mWxsFhHMi7%Gqz!v(Osc5WxK+^1PGfsozw)FE}VIxk9GexmAohPNAF*SAjxG3Al#(xQoYXdI}TR zoCHAFS6+LDqsP8L1SZH{RxJjFK_=vy4nNH^?M!OsQWe^qC~$c1r&y`H9n5;D z2F$t-Htc%2@K(>opJHE{NytI2<_J<6Kz*p$wtKUTEH}zITx?H0L%!5%i@!rLphSBrkFs>jscP6?HVQovX8!~b~ZY|0h%&souT7e5nD@OxuSgC zVW*eo0B|1POwg7;6fJSUC`g+`1%XQvwpRc*&|AtV*h!#5nQM(@m!K)-Qop!Rt3F`a z9HUO zF3w{uI_==EpjFQWV4boF^A?wc@@@U+KrKPjn6sK{OLu-~1UloSqt-aHYo*^@kQy2+ zH(9*-mFz?YV4cL7EW)9hsdmG{5jaYXLvm*&3PZ4y?8z`$9z6`q9fgsJm@*W$-QSzu zut}57hroSbTd=&RJpuy#?K?A6!-;_MowpK8eb~5T-^eye%3O-T^ktSMbd%PT0j-B?#yAKr37u%gB z*2)WJMw6Y)6BvY$JjD`(06ci7u;u$hv}gN5oS&Q^*y$J6L)0#BD<>XL|;pZgtZaxp3~$0zxA(;6Qr_AP$?8l@S)C^Hoaz#rQFK^lA}3&)Gr}Fsca? zK>9BkVcl;c*E2P9UMppEIB&38dL9R?Xg9N{Nl~4*w!qsZJElz}Xc9gz#}cwnP4u{+ z6VNTEx*>u67?3bn{sWk*P`1_$YfsB+)Ax0+jt|)0p&VS?N0k8IAp2KH_#eY3I#{Hw zB$vObUDtXyZX)*wVh*@BefnUej#jv@%uiA=>ngX0kQXaz>8(WM)fX~v__@I}7|!Il z@J%r#I!JqqFwGd4JPhmDmL>1Bh}nn_BE;hgKUesNOf9zQhiuhn%4B}O8jnxEwJiQFDaiiuXw2sb?*8a}Lr;_#7+IPfIjhVDhazSpbQZECL+4)p8lO;)!y>Rt=0X*;O# zX{s(p-*d{#{Y3gVhL;A{4a(Z5sIfpk;WMCqdFA&Mb7mp;YMXhBF@p`}$ShAug+bo`;<9fm!~F z-;1yCj$GQ^mzucrfuatilXrYLr)`izjn_m(f~);txN?D7d?Kg4wDuPXilVyeVwjzf z=4Kewf=u}X_H*viVfPWZW?Sqa3G#h3|;b!Q7>BRc7-Wox0}&>}Lqo=0v;T_i~% zqB&h;14|~nK{W0N=$obGP@O%(c8SraYS^qiu%Q`B zBHdA!`Vk7#Bz*@_3eE#bizLzjBV;F0vfSA~+7@8+F{$7Y?fwI~Pp_X`2ORgqW6g@2 z{cQV!niSsMEVr1IaeRAj8~|*4yW~X5$6o`crw4uTHhgPs^qAk?9UPu;xy5wh2^jZ; z)@27Q=QKa?8w7_C0|u`@k=%b9Ce$D7x42CdLsckF2<$wLuV2kpik8PXex2^Co$n2o z)l#H*;#>?yrPw0x6LI@x(X$nezCBa0Obi%|I5ZV|4bJSPtNHjDkS|3S?fiv(i_(n* zFbve0g!B0!MMmakRsgg_if8nwImb=kk%|s+08xGQ)J?vpkdaya3UD|RJK+LQ72|g> zc4LnwInx!2pN-5Yvp7rvRF#B=(ZO8gyVB^0Dh#ZdHA2BjjppfV<=2Nm#w_t{%6O$W z`-?7N?LwL0DWgK0Y7L#ChSHfa{=DOpJpl8L@V70cd%ei)n%SQO;Z+Xw#li#%LUfbs z&hP%UzN(qM3cw#bWQS6_B@>1^ea-AqNA12xoiQeb_Zdtf>yHljqeIHqlyC^gzH)h1 zstXTFEb0r=l9;><<$a}YWlscH7VW_xeKVZ#*#v#HiuUOs7PPj8ml4#!BiGEK)kDpO zX=2mU0ZuIDDnhfV7v_Rs)0R#ff6I6_|MrzV(R$3Nt#S7D?GQy6?a^WRvA@r2~?7f~s99*9;fuqJ(843U`hRl2O|sk>J@WMsR2O zwyZt$@J)DnSUNkF@B3MPNz|<@`72{M*S5d<1Vkg+G=q~u{8OP84Yh6VCE5pNC*#m> z*jzHy5Tc82sBVw+6W7DoR5@LXZ|+>;)Q%czg%8pyMyeE2-)R^oHg~SrO~#I8MxNc> z6pWT&F&H1mX7#2@mBY>#rRoFKszT z(gvV#j3x|7sF|Dt0*CgsJTdH1R!>inYZWp*2RDbjjQCP98L_ds!$x&{t85NRYk4ii ztJ3HyC8h2A2&`kq^Cfci>N*r&btHg_|v6=s|v=(-MQ zK4kjqoI^~y`j9poC2r{Izdlehm8!AcMP^+SwDUce1Zon(%YvxK)x|rXsJRlO?-K91 zMsmHgI&PmqT_W}C0mdA_6L!EEjgJzidRvTN;vQRJ-uBl#{dEeN?24PRwx)7c5kF^ut=M0)e@zr?z_vpYf=%;;@UYF9>9-->Qf2FW*# z5*#VFB$$-k(zphh4sAElMiLbp`$+SKm*{l6qX;Q8GZ7b|J>OhC!yg$}8dt$dx3E8b z$FlaM*K@6mSsYCoe#*QjLEB3|_Vs4GbZI#!>Ya}dzh%uMn}sw0gFQQ{+V+e|_`q)M3nK27)nAqQ-viJoPHUKdr9HN`v0 z+tZo0ORLuv_d)x}gO|~s(H!12RM(aMfqLG>KSH#kGxC{sUUj>FUC(6;ds1cOjeDYu zOrd>q@bNFq5?0s&@5nbF3-rw{{V&YYf3o_9|K-X4k861UwZ&C2bH+A7^%7nizU>b? zC2@*VlrqprJiv$rx{+^+Op9i3RM;IHq@a;34=Gn%B+rXMZi=UsHC@TEFk4{*fs96p z)wNUY?AhVkdLGQmPESuh@-!iqSZrnxIT~Mon)J+i+B~9VdL8QE`^4=2@lNaKluUVx z_^i7~5E4dN4&gVMi%;7ast@WIY21Q`+^iTC*Gx@IMVYB`BLFHzPh{Fpc6LKZTk@>P zquo2E*Pgq(0MX>h>4)YaJYbIK&V?-W}JfL@&R0I2)TOA!Teg zNa4DBO&)`Nn0$Inb|d8ea|)qqOLYVbQIBRC4T4E<5#Nzc2 z57|Bq7mYsW8y?uLA$XMj%OeK+1|DAKcLYB98-vDP<3*+SKYcPcOkm&}H|!{9l*9%L zbiYJYJ^)Cql-&wPwABGD>Ai7SUXe15m zIr^wNEU$9)D6@atm z(w(1~GuLpHi?JGgIBj`Ovy;j4M`XjrCNs?JsGh1zKsZ{8 z@%G?i>LaU7#uSQLpypocm*onI)$8zFgVWc7_8PVuuw>u`j-<@R$Of}T`glJ!@v*N^ zc(T~+N+M!ZczPSXN&?Ww(<@B=+*jZ+KmcpB8* zDY_1bZ3fwTw|urH{LLWB;DCGzz$jD|VX#Af@HC%BktA8F7VJSy&!5iTt};#U^e0_q zh6j7KCTInKqriZ1`BiF3iq2LWk;gyt0ORIFc4Mi3Bx`7WEuFq{u^C49-SYVjnv!_40m1>7x*+<8~Xkq?056 z!RBfE@osP%SxzOw>cLAQ$bioAOC0V!OzIXIc};)8HjfPtc~8tnah$PtoAz`4k)7$FDUc2O@D)g_uAo&nXMymK$##V?gYUPt^l zj{6NFDL(l-Rh(xkAHP%bBa=($r%3Y~jB!eQ1Smuq2iuQ|>n%Y=p(26SE5gFu11*Q< zaPN5G^d;Iovf`VY&Gh58z~%JpGzaeUz6QoBL^J%+U4|30w7Q&g9i}}@l61eKEfCgo zST6qMxF_Eaj7;0OC)TSU{4_m}%FOa6B{AxS$QIcmmG~IVjjf;7Uk!HBtHfm{%LsLb zu8~5VQFyOZk&!VY(wxL__haJ;>Bj?g&n`+i&=X{unJmv&0whCitWfGlOr6+Tc-lMZ z(ZRXqC-=O+GAvTXKViA9vdwu{aifhk$tYh~-9BScg!Yr*M2zw&9`pHMxHGh`dUH-1;~^6lF@ep;X9PjQ!rqmXNWJ?#P-qb%*TB%xe&3 zX*5V>xuW7)$3!Yc$y>cwBqd8+p+u>WS7p7~O80ipG{(a*#=NJ`^Ld6k-`|;Y&htFy zIi2(Sm)4eD=o+CGo~M3%qF|O9P0+ahmc%EklI?NgX05W3+OdS`_Rd#wg-}hd1&txU5wXy zy`x)05?WVZvELw`XWetIAg6$|(^4ntaE;=f$Wcpwbxm7?bLDnPs-1!bRoMcy!EeOh zpIv8ewDzcIU}mv1NxV!&(Wf7~_kqGAk=2=j&O5FA)z2!APCcDQPnIaiqMkVT4fUyX z))R|WvOJyzcU6d=z0q8JDt42*`js4g+_t{YP7lVguX+vhEejJ3TAIo*Z6jizHm#S- zZT_}-STQAa-0Gn8+RmR7V}{Ns1@jJ{^Sb!9&RSXXP;^ep)r6;&PW++~XYXC9a=zSF z?sp(JQo&MROb~b1Y*Xw4!P)>PHT>Z<)*U=Ax_75^OUw97pNudbxS1XPtNrIg zQ5YB77E@i7$2Ia}(^JcCi@OX`9a|m}PY%-th2m~y+)eCl>fTVjCP^lDOBLyhg1DZ+ z)~G{&OkDc$!;t~`gq(wz@qW3lh9B^ic$>-h#nV!H8d#l+>C(M%g}u2g=I#&W|L!VD zqHYoQkBW;`r|fW02u{7X!X;}T7X4iAaWzkeOh}7&o!F1qt4#$1|BDF;(2VlgEqJ$F zy8Ba-y(%fs`MzpvyXlQLEhS^ed$7Va2hO%?$-D>^*f$b)2Hx;}Ao$UqFt7l26<7eP z!{!C7PVrq>=794Zqmc z%LKkzIBZq@%Ja8EkH}?>c5ILG(EAMS*JHu?#9_7TsELw)8LZzN>f2Y6YN{AJC?34> zh42sPa1%2JpCeS9&E1URm+Pb}B>A1M`R{+O+2~}c(@^1Rf&J9p(4QqHl;E^4w5;I5 zM{?(A^eg*6DY_kI*-9!?If^HaNBfuh*u==X1_a?8$EQ3z!&;v2iJ``O7mZh%G)(O8 ze<4wX?N94(Ozf9`j+=TZpCbH>KVjWyLUe*SCiYO=rFZ4}S~Tq|ln75Jz7$AcKl$=hub=-0RM1s(0WMmE`(OPtAj>7_2I5&76hu2KPIA0y;9{+8yKa;9-m??hIE5t`5DrZ8DzRsQ+{p1jk-VFL9U z2NK_oIeqvyze>1K%b|V?-t;Wv`nY~?-t;tMC4ozyk8CR(hoZTno3!*8ZTc15`?MFf zDI892&g&3lshOEv4E@w-*_%)8C_<&HhV`0D5lN$WT4Q^UWHNSAE+RZe(o z%bqR^hp1IsDr47e^AajFtlppT)2F6yPcrWO9{Kw{o=P6y^HOW$Wqd_)_fwzn`ikZl zOGVc0+S(*=xZ_KbL0Nr`Sx$$CWEbw$52udl1f=X6CZEcFMA*nl>`0gn4&tc5^`!!)tGw<}^Q>P7E}$ zialDUofH*XcB3r9@tA@lnS}dA(@nK_xuw0b;FPUnNGD0;MIySCw=cSzB#=3>F37V-nni3UNB)-;;Gkk;3l9fh6FIjSZU zk=Eo2a`6i7@i*4>ym5`R?i-uZFv6+iX*Gi^I}ZU1OrLAX8aGiT@`*YnjeF>}$U}ORP`+EY5`eqVC_&4yG z;Tp>+2QbZ?lt1GB+D}q14W3dWP8lWnN zf(nlT6+XW&(zme{FbyDpP^NakA<~TK=Y}H^eS%2rt0v8Lr)B}@B!cTvC=9FM;7q4@ zf*;vb4HG>RFpY5?vFCp27VEnVIGx~-na6biU4{+UoYe=}^R#_My6wT$5d&r*=kpAA zu;=-c0|~yqi(N8&*H;aNfhyey+HHQ7J_qae*_CgG2V8j=Tq936S0DC8r3BXBql3Gz z0pLo_`|4Q+oY3rPBNaLmL{QM};9dke>ujP^j@z-N;fNlKb|edn>)YaafDaJ>GWKP$ z5}l&#$QFhN!CMT;WH&z-5E)kvM|36lV!^#3z{@2FF>HsgUO4PMqO#U$X%+U>K!xJ@ zBFs|+woG_9HZQs_Tw*vnCPGhlXG@>y|6pJT$I67!aP&b0o$AF2JwFy9OoapQAk>k7 z**+$_5L;5fKof<;NBX%_;vP@eyD=Z0(QW)5AF7 zp|=tk3p?5)*e~Inuydz-U?%Kuj4%zToS5I|lolPT!B)ZuRVkVa>f*-2aPeV3R79xh zB)3A$>X~szg#}>uNkpLPG#3IKyeMHM*pUuV5=-Jji7S6PSQ9oCLo{oXxzOZfF$PP) zrYwlmSQ-~n94uO3CD{K0QTmj@g%Yzn7_xQ4fTduU0Yqvln`e_`CdXH5iQ5qRr1 zBC;}%YZ2!4I>*=sR)O~jBPx6sxmIEBnq)s-fHz_y0z8-gPl2Us4BiBXNR5CIF!YR@ zb9B305SilU*@4|+ x6JBtc8JSt5M0pkooaq!^FqtuD_KdXXTo>Mw54>`rP&>h&58!3a6l6r9{sG7g--!SK diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 1b16c34a..00000000 --- a/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew deleted file mode 100755 index 2fe81a7d..00000000 --- a/gradlew +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## 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='"-Xmx64m" "-Xms64m"' - -# 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 or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; 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=`expr $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" - -exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat deleted file mode 100644 index 9618d8d9..00000000 --- a/gradlew.bat +++ /dev/null @@ -1,100 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@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="-Xmx64m" "-Xms64m" - -@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 diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..c189035e --- /dev/null +++ b/pom.xml @@ -0,0 +1,105 @@ + + + 4.0.0 + + me.techscode + techdiscordbot + + TechDiscordBot + 0.2.0 + jar + + + Greazi + me.techscode.techdiscordbot.TechDiscordBot + + 17 + + 17 + 17 + + UTF-8 + + + + + jitpack.io + https://jitpack.io + + + + + + com.greazi + DiscordBotFoundation + 0.24.0 + + + + + com.google.code.gson + gson + 2.10.1 + + + + net.sourceforge.tess4j + tess4j + 5.7.0 + + + + + + + ${project.name} + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.2 + + + + ${main.class} + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + + + false + + + + + + + src/main/resources + true + + + + \ No newline at end of file diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index 907cb5e1..00000000 --- a/settings.gradle +++ /dev/null @@ -1,3 +0,0 @@ -rootProject.name = 'TechDiscordBot' - -include ":SpigotAPI" \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/TechDiscordBot.java b/src/main/java/me/TechsCode/TechDiscordBot/TechDiscordBot.java index 11fb354c..951beb33 100644 --- a/src/main/java/me/TechsCode/TechDiscordBot/TechDiscordBot.java +++ b/src/main/java/me/TechsCode/TechDiscordBot/TechDiscordBot.java @@ -1,288 +1,209 @@ -package me.TechsCode.TechDiscordBot; - -import me.TechsCode.TechDiscordBot.module.ModulesManager; -import me.TechsCode.TechDiscordBot.mysql.MySQLSettings; -import me.TechsCode.TechDiscordBot.mysql.storage.Storage; -import me.TechsCode.TechDiscordBot.objects.ChannelQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.reminders.ReminderManager; -import me.TechsCode.TechDiscordBot.songoda.SongodaAPIClient; -import me.TechsCode.TechDiscordBot.spigotmc.SpigotApi; -import me.TechsCode.TechDiscordBot.spigotmc.data.APIStatus; -import me.TechsCode.TechDiscordBot.util.Config; -import me.TechsCode.TechDiscordBot.util.ConsoleColor; -import me.TechsCode.TechDiscordBot.util.PterodactylAPI; -import net.dv8tion.jda.api.JDA; -import net.dv8tion.jda.api.JDABuilder; -import net.dv8tion.jda.api.entities.*; -import net.dv8tion.jda.api.hooks.AnnotatedEventManager; -import net.dv8tion.jda.api.requests.GatewayIntent; -import net.dv8tion.jda.api.utils.ChunkingFilter; -import net.dv8tion.jda.api.utils.MemberCachePolicy; -import net.dv8tion.jda.api.utils.cache.CacheFlag; -import okhttp3.OkHttpClient; - -import javax.security.auth.login.LoginException; -import java.util.Arrays; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -public class TechDiscordBot { - - private static JDA jda; - private static TechDiscordBot i; - - private static Guild guild; - private static Member self; - - private static SpigotApi spigotAPI; - private static SongodaAPIClient songodaAPIClient; -// private static List songodaPurchases; - - private static Storage storage; - - private static String githubToken; - - private static ModulesManager modulesManager; - private static ReminderManager remindersManager; - - private static PterodactylAPI pterodactylAPI; - - public static void main(String[] args) { - if (!Config.getInstance().isConfigured()) { - log(ConsoleColor.RED + "Invalid config file. Please enter the information in config.json"); - return; - } - - try { - new TechDiscordBot(Config.getInstance().getToken(), Config.getInstance().getApiToken(), Config.getInstance().getSongodaApiToken(), MySQLSettings.of(Config.getInstance().getMySqlHost(), Config.getInstance().getMySqlPort(), Config.getInstance().getMySqlDatabase(), Config.getInstance().getMySqlUsername(), Config.getInstance().getMySqlPassword()), Config.getInstance().getGithubToken(), Config.getInstance().getPteroUrl(), Config.getInstance().getPteroClientToken(), Config.getInstance().getPteroApiToken(), Config.getInstance().getSpigotApiUrl()); - } catch (LoginException | InterruptedException e) { - e.printStackTrace(); - } - } - - public TechDiscordBot(String token, String apiToken, String songodaApiToken, MySQLSettings mySQLSettings, String githubToken, String pteroUrl, String pteroClientToken, String pteroApiToken, String spigotApiUrl) throws LoginException, InterruptedException { - i = this; - - jda = JDABuilder.createDefault(token) - .setEnabledIntents(GatewayIntent.getIntents(GatewayIntent.DEFAULT | GatewayIntent.GUILD_MEMBERS.getRawValue() | GatewayIntent.GUILD_BANS.getRawValue())) - .setDisabledIntents(GatewayIntent.DIRECT_MESSAGE_TYPING, GatewayIntent.GUILD_MESSAGE_TYPING) - .enableCache(CacheFlag.ONLINE_STATUS) - .disableCache(CacheFlag.ACTIVITY, CacheFlag.VOICE_STATE) - .setMemberCachePolicy(MemberCachePolicy.ALL) - .setChunkingFilter(ChunkingFilter.ALL) - .setActivity(Activity.watching("for help.")) - .setEventManager(new AnnotatedEventManager()) - .build().awaitReady(); - - List guilds = jda.getGuilds(); - - if(guilds.size() > 2) { - log(ConsoleColor.RED + "The bot is a member of too many guilds. Please leave them all except two!"); - return; - } - - if(guilds.size() == 0) { - log(ConsoleColor.RED + "The bot is not a member of any guild. Please join a guild!"); - return; - } - - guild = jda.getGuildById("311178000026566658"); - self = guild != null ? guild.getSelfMember() : null; - - if(guild == null) { - log(ConsoleColor.RED + "The bot is not in the right guild!"); - return; - } - - TechDiscordBot.githubToken = githubToken; - - spigotAPI = new SpigotApi(spigotApiUrl, apiToken); - songodaAPIClient = new SongodaAPIClient(songodaApiToken); - - log("Initializing MySQL Storage " + mySQLSettings.getHost() + ":" + mySQLSettings.getPort() + "!"); - storage = Storage.of(mySQLSettings); - - if(!storage.isConnected()) { - log(ConsoleColor.RED + "Failed to connect to MySQL!"); - log(storage.getLatestErrorMessage()); - } - - pterodactylAPI = new PterodactylAPI(); - pterodactylAPI.setup(pteroUrl, pteroClientToken, pteroApiToken); - - modulesManager = new ModulesManager(); - log("Loading modules.."); - modulesManager.load(); - - remindersManager = new ReminderManager(); - log("Loading reminders.."); - remindersManager.load(); - - jda.addEventListener(modulesManager); - jda.addEventListener(remindersManager); - - Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.OFF); - - log("Successfully loaded the bot and logged into " + guild.getName() + " as " + self.getEffectiveName() + "!"); - - log(""); - - log("Spigot:"); - if(!getSpigotStatus().isUsable()) { - log(" > " + ConsoleColor.RED + "API is not usable!"); - }else{ - log(" > Purchases: " + getSpigotAPI().getSpigotPurchases().size()); - log(" > Resources: " + getSpigotAPI().getSpigotResources().size()); - log(" > Updates: " + getSpigotAPI().getSpigotUpdates().size()); - log(" > Reviews: " + getSpigotAPI().getSpigotReviews().size()); - } - log(""); - - log("Market:"); - if(!getMarketStatus().isUsable()) { - log(" > " + ConsoleColor.RED + "API is not usable!"); - }else{ - log(" > Purchases: " + getSpigotAPI().getMarketPurchases().size()); - log(" > Resources: " + getSpigotAPI().getMarketResources().size()); - log(" > Updates: " + getSpigotAPI().getMarketUpdates().size()); - log(" > Reviews: " + getSpigotAPI().getMarketReviews().size()); - } - log(""); - - log("Songoda: "); - if(getSongodaAPI().isLoaded()) { - log(" > Purchases: " + getSongodaAPI().getSpigotPurchases().size()); - } else { - log(" > " + ConsoleColor.RED + "Could not connect. Cannot show info!"); - } - - log(""); - - log("Guild:"); - log(" > Members: " + getGuild().getMembers().size()); - log(" > Verified Members: " + getStorage().retrieveVerifications().stream().filter(v -> guild.getMemberById(v.getDiscordId()) != null).count()); - log(" > Review Squad Members: " + getGuild().getMembers().stream().filter(member -> member.getRoles().stream().anyMatch(role -> role.getName().equals("Review Squad"))).count()); - log(" > Donators: " + getGuild().getMembers().stream().filter(member -> member.getRoles().stream().anyMatch(role -> role.getName().contains("Donator"))).count()); - - log(""); - - getModulesManager().logLoad(); - - log(""); - log("Startup Completed! The bot has successfully started!"); - log("The bot is ready"); - } - - public static JDA getJDA() { - return jda; - } - - public static TechDiscordBot getBot() { - return i; - } - - public static Guild getGuild() { - return guild; - } - - public static Member getSelf() { - return self; - } - - public static Storage getStorage() { - return storage; - } - - public static SpigotApi getSpigotAPI() { - return spigotAPI; - } - - public static PterodactylAPI getPterodactylAPI(){return pterodactylAPI;}; - - public static SongodaAPIClient getSongodaAPI() { - return songodaAPIClient; - } - - public static ModulesManager getModulesManager() { - return modulesManager; - } - - public static ReminderManager getRemindersManager() { - return remindersManager; - } - - public Query getRoles(String... names) { - List roles = Arrays.stream(names).flatMap(name -> guild.getRolesByName(name, true).stream()).collect(Collectors.toList()); - - return new Query<>(roles); - } - - public ChannelQuery getChannels(String... names) { - List channels = Arrays.stream(names).flatMap(name -> guild.getTextChannelsByName(name, true).stream()).collect(Collectors.toList()); - return new ChannelQuery(channels); - } - - public TextChannel getChannel(String id) { - return guild.getTextChannelById(id); - } - - public Query getCategories(String... names) { - List channels = Arrays.stream(names).flatMap(name -> guild.getCategoriesByName(name, true).stream()).collect(Collectors.toList()); - return new Query<>(channels); - } - - public Query getMembers(String... names) { - List channels = Arrays.stream(names).flatMap(name -> guild.getMembersByName(name, true).stream()).collect(Collectors.toList()); - return new Query<>(channels); - } - - public Member getMember(String id) { - return guild.getMemberById(id); - } - - public Query getEmotes(String... names) { - List emotes = Arrays.stream(names).flatMap(name -> guild.getEmotesByName(name, true).stream()).collect(Collectors.toList()); - - return new Query<>(emotes); - } - - public static Member getMemberFromString(Message msg, String s) { - if (msg.getMentionedMembers().size() > 0) { - return msg.getMentionedMembers().get(0); - } else if (getGuild().getMembers().stream().anyMatch(mem -> (mem.getUser().getName() + "#" + mem.getUser().getDiscriminator()).equalsIgnoreCase(s) || mem.getUser().getId().equalsIgnoreCase(s))) { - return getGuild().getMembers().stream().filter(mem -> (mem.getUser().getName() + "#" + mem.getUser().getDiscriminator()).equalsIgnoreCase(s) || mem.getUser().getId().equalsIgnoreCase(s)).findFirst().orElse(null); - } - return null; - } - - public static boolean isStaff(Member member) { - return member.getRoles().stream().anyMatch(r -> r.getName().contains("Supporter") || r.getName().contains("Staff")); - } - - public static void log(String prefix, String message) { - System.out.println(prefix + " " + ConsoleColor.RESET + message + ConsoleColor.RESET); - } - - public static void log(String message) { - System.out.println("[TechPluginSupport] " + message + ConsoleColor.RESET); - } - - public static String getGithubToken() { - return githubToken; - } - - public static APIStatus getSpigotStatus() { - return APIStatus.getSpigotStatus(spigotAPI.getSpigotAPIManager()); - } - - public static APIStatus getMarketStatus() { - return APIStatus.getMarketStatus(spigotAPI.getSpigotAPIManager()); - } - - public static APIStatus getSongodaStatus() { - return APIStatus.getStatus(getSongodaAPI()); - } +package me.techscode.techdiscordbot; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.SimpleBot; +import com.greazi.discordbotfoundation.utils.color.ConsoleColor; +import me.techscode.techdiscordbot.actions.buttons.ApplyButton; +import me.techscode.techdiscordbot.actions.buttons.TicketButtons; +import me.techscode.techdiscordbot.actions.buttons.verification.*; +import me.techscode.techdiscordbot.commands.applications.ApplicationCommand; +import me.techscode.techdiscordbot.commands.common.*; +import me.techscode.techdiscordbot.commands.console.SayConsoleCommand; +import me.techscode.techdiscordbot.commands.debug.DatabaseCommand; +import me.techscode.techdiscordbot.commands.staff.*; +import me.techscode.techdiscordbot.commands.staff.punishment.BanCommand; +import me.techscode.techdiscordbot.commands.staff.punishment.KickCommand; +import me.techscode.techdiscordbot.commands.staff.punishment.TimeoutCommand; +import me.techscode.techdiscordbot.commands.staff.punishment.WarnCommand; +import me.techscode.techdiscordbot.commands.tickets.TicketCommand; +import me.techscode.techdiscordbot.commands.tickets.TicketStaffCommand; +import me.techscode.techdiscordbot.commands.verification.CodeCommand; +import me.techscode.techdiscordbot.database.TranscriptSqlManager; +import me.techscode.techdiscordbot.model.reminders.ReminderManager; +import me.techscode.techdiscordbot.modules.*; + +import java.sql.SQLException; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public final class TechDiscordBot extends SimpleBot { + + public static TranscriptSqlManager transcriptSqlManager; + + private static ReminderManager remindersManager; + + /** + * A very ugly way of starting the bot but there is no other way + * of doing this. This might get fixed in the feature + * + * @param args Arguments passed to the bot + */ + public static void main(final String[] args) { + // The method that starts the whole bot + new SimpleBot() { + + @Override + public void onPreLoad() { + } + + @Override + protected void onBotLoad() { + Common.log(Common.consoleLine(), + ConsoleColor.CYAN + " Starting the bot " + SimpleBot.getName() + " V" + getVersion(), + Common.consoleLine() + ); + + transcriptSqlManager = new TranscriptSqlManager(); + + //Database.MEMBERS.createTable(); + } + + @Override + protected void onBotStart() { + } + + @Override + protected void onReloadableStart() { + + /* + * Register all commands here + */ + registerCommands( + new UserInfoCommand(), + new CodeCommand(), + new GoogleCommand(), + new AnswerCommand(), + new PluginCommand(), + new RemindCommand(), + new ApplicationCommand(), + new TicketCommand(), + new TicketStaffCommand(), + new LinkCommand(), + new QuestionCommand(), + new RoleCommand(), + new WikiCommand(), + new UpdateCommand() + ); + + registerCommands( + new BanCommand(), + new KickCommand(), + new TimeoutCommand(), + new WarnCommand(), + new BotCommands() + ); + + // Register all debug commands + registerCommands( + new DatabaseCommand() + ); + + /* + * Add all events here + */ + getJDA().addEventListener(new PrivateMessageReceiveModule()); + getJDA().addEventListener(new BotMentionModule()); + getJDA().addEventListener(new MemberJoinModule(), new MemberLeaveModule()); + getJDA().addEventListener(new RolesModule()); + getJDA().addEventListener(new MessageReceive()); + + /* + * Add all console command here + */ + registerConsoleCommand(new SayConsoleCommand()); + + /* + * All other methods down here + */ + // Send the verification embed + /*VerificationModule.embed(); + TicketModule.embed(); + ApplyModule.embed();*/ + + + new TicketButtons.TicketButton().build(); + new ApplyButton.Button().build(); + new VerifyButton.Button().build(); + + remindersManager = new ReminderManager(); + Common.log("Loading reminders.."); + try { + remindersManager.load(); + } catch (final SQLException e) { + throw new RuntimeException(e); + } + + jda.addEventListener(remindersManager); + + /* + * A new thread to check for preorders + * Ugly, but it works + */ + /*if (Settings.Modules.Preorder.enabled) { + Common.log("Preorder system enabled", + "Checking for preorders every 15 minutes.."); + // Check the preorders on startup + PreorderModule.CheckPreorders(); + + new Thread(() -> { + while (true) { + try { + Thread.sleep(TimeUnit.MINUTES.toMillis(15)); + Debugger.debug("Checking for preorders.."); + PreorderModule.CheckPreorders(); + } catch (final InterruptedException e) { + Common.throwError(e, "Error while sleeping the preorder thread"); + } + } + }).start(); + }*/ + + // Run this method every hour + ScheduledExecutorService executor = Executors.newScheduledThreadPool(1); + + executor.scheduleWithFixedDelay(new Runnable() { + @Override + public void run() { + Common.log("Checking all verification channels.."); + VerificationModule.pinger(getMainGuild()); + } + }, 5, 60, TimeUnit.MINUTES); + + } + }; + } + + @Override + protected void onBotStart() { + } + + @Override + public String[] getStartupLogo() { + return new String[]{ + " ______ __ ____ _ ______ __ ", + " /_ __/__ _____/ /_ / __ \\(_)_____________ _________/ / __ )____ / /_", + " / / / _ \\/ ___/ __ \\/ / / / / ___/ ___/ __ \\/ ___/ __ / __ / __ \\/ __/", + " / / / __/ /__/ / / / /_/ / (__ ) /__/ /_/ / / / /_/ / /_/ / /_/ / /_ ", + "/_/ \\___/\\___/_/ /_/_____/_/____/\\___/\\____/_/ \\__,_/_____/\\____/\\__/ " + }; + } + + @Override + public int getFoundedYear() { + return 2022; + } + + @Override + public String getVersion() { + return "0.1.25"; + } + + public static ReminderManager getRemindersManager() { + return remindersManager; + } + + public static TranscriptSqlManager getTranscriptSqlManager() { + return transcriptSqlManager; + } } diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/ApplyButton.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/ApplyButton.java new file mode 100644 index 00000000..006ff6a9 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/ApplyButton.java @@ -0,0 +1,153 @@ +package me.techscode.techdiscordbot.actions.buttons; + +import com.greazi.discordbotfoundation.handlers.buttons.SimpleButton; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.actions.modals.ApplicationModal; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; +import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; +import org.jetbrains.annotations.NotNull; + +import java.util.concurrent.CompletableFuture; + +import static me.techscode.techdiscordbot.modules.ApplyModule.applicationCreate; + +public class ApplyButton { + + public static class Button extends SimpleButton { + + public Button() { + super("Apply_Create"); + label("Create Application"); + emoji(Emoji.fromUnicode("📝")); + buttonStyle(ButtonStyle.SUCCESS); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + + CompletableFuture future = applicationCreate(getMember(), getGuild()); + future.thenAccept(channel -> { + event.replyEmbeds(new SimpleEmbedBuilder("Application Created") + .text( + "A new application has been created.", + "Please follow the steps in " + channel.getAsMention() + ) + .success().build()).setEphemeral(true).queue(); + }); + } + } + + public static class GeneralQuestionButton extends SimpleButton { + + public GeneralQuestionButton(@NotNull Member member) { + super("AGQ_" + member.getIdLong()); + label("Answer Questions"); + emoji(Emoji.fromUnicode("❓")); + buttonStyle(ButtonStyle.PRIMARY); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + event.replyModal(new ApplicationModal.GeneralQuestions(getMember()).build()).queue(); + this.remove(); + } + } + + public static class SupportQuestions extends SimpleButton { + + public SupportQuestions(@NotNull Member member) { + super("AGQS_" + member.getIdLong()); + label("Answer Questions"); + emoji(Emoji.fromUnicode("❓")); + buttonStyle(ButtonStyle.PRIMARY); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + event.replyModal(new ApplicationModal.Support(getMember()).build()).queue(); + this.remove(); + } + } + + public static class DeveloperQuestions extends SimpleButton { + + public DeveloperQuestions(@NotNull Member member) { + super("AGQS_" + member.getIdLong()); + label("Answer Questions"); + emoji(Emoji.fromUnicode("❓")); + buttonStyle(ButtonStyle.PRIMARY); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + event.replyModal(new ApplicationModal.Developer(getMember()).build()).queue(); + this.remove(); + } + } + + public static class MarketingQuestions extends SimpleButton { + + public MarketingQuestions(@NotNull Member member) { + super("AGQS_" + member.getIdLong()); + label("Answer Questions"); + emoji(Emoji.fromUnicode("❓")); + buttonStyle(ButtonStyle.PRIMARY); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + event.replyModal(new ApplicationModal.Marketing(getMember()).build()).queue(); + this.remove(); + } + } + + public static class CommunityHelperQuestions extends SimpleButton { + + public CommunityHelperQuestions(@NotNull Member member) { + super("AGQS_" + member.getIdLong()); + label("Answer Questions"); + emoji(Emoji.fromUnicode("❓")); + buttonStyle(ButtonStyle.PRIMARY); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + event.replyModal(new ApplicationModal.CommunityHelper(getMember()).build()).queue(); + this.remove(); + } + } + + public static class ExitQuestions extends SimpleButton { + + public ExitQuestions(@NotNull Member member) { + super("AGQE_" + member.getIdLong()); + label("Answer Questions"); + emoji(Emoji.fromUnicode("❓")); + buttonStyle(ButtonStyle.PRIMARY); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + event.replyModal(new ApplicationModal.ExitQuestions(getMember()).build()).queue(); + this.remove(); + } + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/BotActionButtons.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/BotActionButtons.java new file mode 100644 index 00000000..52d8713d --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/BotActionButtons.java @@ -0,0 +1,64 @@ +package me.techscode.techdiscordbot.actions.buttons; + +import com.greazi.discordbotfoundation.handlers.buttons.SimpleButton; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.actions.modals.ShutdownModal; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; +import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; +import org.jetbrains.annotations.NotNull; + +public class BotActionButtons { + + public static class shutdown extends SimpleButton { + public shutdown() { + super("shutdown"); + label("CONFIRM SHUTDOWN"); + buttonStyle(ButtonStyle.DANGER); + disabled(false); + mainGuildOnly(); + + new Thread(() -> { + try { + Thread.sleep(300000); + this.remove(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + + event.replyModal(new ShutdownModal(event.getMember().getId()).build()).queue(); + } + } + + public static class restart extends SimpleButton { + public restart() { + super("restart"); + label("CONFIRM RESTART"); + buttonStyle(ButtonStyle.DANGER); + disabled(false); + mainGuildOnly(); + + new Thread(() -> { + try { + Thread.sleep(300000); + this.remove(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }).start(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + + event.replyEmbeds(new SimpleEmbedBuilder("Restarting...") + .text("The bot is now restarting.") + .success().build()).queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/DeleteButton.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/DeleteButton.java new file mode 100644 index 00000000..419891eb --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/DeleteButton.java @@ -0,0 +1,36 @@ +package me.techscode.techdiscordbot.actions.buttons; + +import com.greazi.discordbotfoundation.handlers.buttons.SimpleButton; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; +import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; + +import java.util.Objects; + +public class DeleteButton extends SimpleButton { + + public DeleteButton(String memberId) { + super("x:" + memberId); + label(""); + emoji(Emoji.fromFormatted("❌")); + buttonStyle(ButtonStyle.SECONDARY); + } + + @Override + protected void onButtonInteract(ButtonInteractionEvent event) { + String MemberId = event.getButton().getId().split(":")[1]; + + Member member = event.getMember(); + + if (member.getId().equals(MemberId) || member.getRoles().contains(Objects.requireNonNull(event.getGuild()).getRoleById(Settings.Roles.staff))) { + event.getMessage().delete().queue(); + remove(); + } else { + // Send a message for a quick seconds to show that the button was pressed + event.reply("You can't delete this message!").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/TicketButtons.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/TicketButtons.java new file mode 100644 index 00000000..2c385e00 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/TicketButtons.java @@ -0,0 +1,63 @@ +package me.techscode.techdiscordbot.actions.buttons; + +import com.greazi.discordbotfoundation.handlers.buttons.SimpleButton; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.actions.menus.TicketMenus; +import me.techscode.techdiscordbot.database.entities.SqlTicket; +import me.techscode.techdiscordbot.modules.TicketModule; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; +import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; + +public class TicketButtons { + + public static class TicketButton extends SimpleButton { + + public TicketButton() { + super("Ticket_Create"); + emoji(Emoji.fromUnicode("📨")); + label("Create a ticket"); + buttonStyle(ButtonStyle.SUCCESS); + disabled(false); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(final @NotNull ButtonInteractionEvent event) { + + CompletableFuture future = TicketModule.ticketCreate(getMember(), getGuild(), getMember()); + + future.thenAccept(channel -> { + + if (channel == null) { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Creation Failed") + .text( + "Your ticket could not be created.", + "You have reached the maximum amount of tickets you can create." + ) + .error().build()).setEphemeral(true).queue(); + return; + } + + // Send a message to the user + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Created") + .text( + "Your ticket has been created.", + "To complete the ticket creation process, please follow the steps in " + channel.getAsMention() + ) + .success().build()).setEphemeral(true).queue(); + }); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/verification/VerifyButton.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/verification/VerifyButton.java new file mode 100644 index 00000000..4fb57fec --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/buttons/verification/VerifyButton.java @@ -0,0 +1,25 @@ +package me.techscode.techdiscordbot.actions.buttons.verification; + +import com.greazi.discordbotfoundation.handlers.buttons.SimpleButton; +import me.techscode.techdiscordbot.actions.modals.VerificationModal; +import me.techscode.techdiscordbot.model.enums.Marketplace; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; +import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; + +public class VerifyButton { + + public static class Button extends SimpleButton { + + public Button() { + super("Verification"); + label("Verify Purchase"); + buttonStyle(ButtonStyle.PRIMARY); + mainGuildOnly(); + } + + @Override + protected void onButtonInteract(ButtonInteractionEvent event) { + event.replyModal(new VerificationModal(this.getUser().getId(), Marketplace.SPIGOT).build()).queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/ApplyMenu.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/ApplyMenu.java new file mode 100644 index 00000000..f0bcd421 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/ApplyMenu.java @@ -0,0 +1,110 @@ +package me.techscode.techdiscordbot.actions.menus; + +import com.greazi.discordbotfoundation.handlers.selectmenu.string.SimpleStringSelectMenu; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.actions.buttons.ApplyButton; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.model.enums.Application; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.interactions.components.selections.SelectOption; +import net.dv8tion.jda.api.interactions.components.selections.StringSelectInteraction; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class ApplyMenu extends SimpleStringSelectMenu { + public ApplyMenu(@NotNull Member member) { + super("APM_" + member.getIdLong()); + placeholder("Select your position"); + minMax(1, 1); + + options( + SelectOption.of(Application.Position.SUPPORT.getName(), Application.Position.SUPPORT.getId()) + .withEmoji(Application.Position.SUPPORT.getEmoji()) + .withDescription(Application.Position.SUPPORT.getDescription()), + + SelectOption.of(Application.Position.DEVELOPER.getName(), Application.Position.DEVELOPER.getId()) + .withEmoji(Application.Position.DEVELOPER.getEmoji()) + .withDescription(Application.Position.DEVELOPER.getDescription()), + + SelectOption.of(Application.Position.MARKETING.getName(), Application.Position.MARKETING.getId()) + .withEmoji(Application.Position.MARKETING.getEmoji()) + .withDescription(Application.Position.MARKETING.getDescription()), + + SelectOption.of(Application.Position.COMMUNITY_HELPER.getName(), Application.Position.COMMUNITY_HELPER.getId()) + .withEmoji(Application.Position.COMMUNITY_HELPER.getEmoji()) + .withDescription(Application.Position.COMMUNITY_HELPER.getDescription()) + ); + } + + @Override + protected void onMenuInteract(@NotNull StringSelectInteraction event) { + final List options = event.getSelectedOptions(); + + for (SelectOption option : options) { + Application.Position category = Application.Position.getById(option.getValue()); + + if (category == null) { + event.reply("An error occurred while processing your request.").setEphemeral(true).queue(); + return; + } + + event.getMessage().delete().queue(); + + if (category == Application.Position.SUPPORT) { + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Support Application") + .text("Please fill out the following form to apply for the Support position.") + .field("Did you help people in the past?", "Have you helped people in the past? If so, please explain how you helped them and what you did to help them.", false) + .field("What plugin are you most skilled in?", "Please explain what plugin you are most skilled in and why you are most skilled in it.", false) + .field("Do you have a microphone?", "Do you have a microphone? If so, are you comfortable to get in a voice chat?", false) + .field("Why should we choose you?", "Why should we choose you over other applicants?", false) + .field("Other", "Feel free to enter any other information you want to share with us.", false) + .build() + ).addActionRow(new ApplyButton.SupportQuestions(getMember()).build()).queue(); + Database.APPLICATIONSTable.setPosition(event.getChannel().getIdLong(), Application.Position.SUPPORT); + + } else if (category == Application.Position.DEVELOPER) { + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Developer Application") + .text("Please fill out the following form to apply for the Developer position.") + .field("What program languages do you know?", "Please explain what program languages you know and what you are most skilled in.", false) + .field("For how long have you been developing?", "How long have you been coding either plugins, websites or other programs?", false) + .field("Do you know how to run a project?", "Did you ever run a project in your past? If so, please explain how you ran it and what you did to run it.", false) + .field("Do you have a GitHub profile?", "Do you have a GitHub profile? If so, please provide a link to it.", false) + .field("Would you sign an NDA?", "Would you sign an NDA (Non-Disclosure Agreement) if we asked you to?", false) + .field("Do you have a microphone?", "Do you have a microphone? If so, are you comfortable to get in a voice chat?", false) + .field("Why should we choose you?", "Why should we choose you over other applicants?", false) + .field("Other", "Feel free to enter any other information you want to share with us.", false) + .build() + ).addActionRow(new ApplyButton.DeveloperQuestions(getMember()).build()).queue(); + Database.APPLICATIONSTable.setPosition(event.getChannel().getIdLong(), Application.Position.DEVELOPER); + + } else if (category == Application.Position.MARKETING) { + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Marketing Application") + .text("Please fill out the following form to apply for the Marketing position.") + .field("What do you expect?", "What do you think you are going to do in our Marketing team?", false) + .field("Which section do you prefer?", "What section in the marketing branch do you prefer to work?", false) + .field("What is your experience?", "What have you done in the past for activities related to this position?", false) + .field("Do you have a graduation?", "Do you have a marketing related graduation? *(not required)*", false) + .field("Can you use designer programs?", "Can you use any tools for designing and such. If so, what are these? *(anything from video editing to photo editing)*", false) + .field("Do you have a microphone?", "Do you have a microphone? If so, are you comfortable to get in a voice chat?", false) + .field("Why should we choose you?", "Why should we choose you over other applicants?", false) + .field("Other", "Feel free to enter any other information you want to share with us.", false) + .build() + ).addActionRow(new ApplyButton.MarketingQuestions(getMember()).build()).queue(); + Database.APPLICATIONSTable.setPosition(event.getChannel().getIdLong(), Application.Position.MARKETING); + + } else if (category == Application.Position.COMMUNITY_HELPER) { + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Developer Application") + .text("Please fill out the following form to apply for the Developer position.") + .field("What languages do you speak/write?", "Give a list of languages you speak/write", false) + .field("Do you have a GitHub profile?", "Do you have a GitHub profile? If so, please provide a link to it.", false) + .field("Do you have a microphone?", "Do you have a microphone? If so, are you comfortable to get in a voice chat?", false) + .field("Why should we choose you?", "Why should we choose you over other applicants?", false) + .field("Other", "Feel free to enter any other information you want to share with us.", false) + .build() + ).addActionRow(new ApplyButton.CommunityHelperQuestions(getMember()).build()).queue(); + Database.APPLICATIONSTable.setPosition(event.getChannel().getIdLong(), Application.Position.COMMUNITY_HELPER); + } + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/RolesMenu.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/RolesMenu.java new file mode 100644 index 00000000..51140ebf --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/RolesMenu.java @@ -0,0 +1,112 @@ +package me.techscode.techdiscordbot.actions.menus; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.handlers.selectmenu.entity.SimpleEntitySelectMenu; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.interactions.components.selections.EntitySelectInteraction; +import net.dv8tion.jda.api.interactions.components.selections.EntitySelectMenu; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class RolesMenu { + + public static class Add extends SimpleEntitySelectMenu { + + public Add(@NotNull Member member) { + super("Add:" + member.getIdLong()); + placeholder("Select the roles"); + minMax(1, 10); + targetType(EntitySelectMenu.SelectTarget.ROLE); + } + + @Override + protected void onMenuInteract(EntitySelectInteraction event) { + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + Member targetMember = event.getGuild().getMemberById(target_id); + List selectedRoles = event.getMentions().getRoles(); + StringBuilder roleMentionBuilder = new StringBuilder(); + + + for (Role role : selectedRoles) { + assert targetMember != null; + if (canUse(event.getMember(), role)) { + SimpleRoles.addRole(targetMember, role); + roleMentionBuilder.append(role.getAsMention()).append(" "); + } + } + + event.editMessageEmbeds(new SimpleEmbedBuilder("Added Roles") + .text("Successfully added the roles " + roleMentionBuilder.toString() + " to " + targetMember.getAsMention()) + .success() + .build() + ).setComponents().queue(); + } + } + + public static class Remove extends SimpleEntitySelectMenu { + + public Remove(@NotNull Member member) { + super("Remove:" + member.getIdLong()); + placeholder("Select the roles"); + minMax(1, 10); + targetType(EntitySelectMenu.SelectTarget.ROLE); + } + + @Override + protected void onMenuInteract(EntitySelectInteraction event) { + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + Member targetMember = event.getGuild().getMemberById(target_id); + List selectedRoles = event.getMentions().getRoles(); + StringBuilder roleMentionBuilder = new StringBuilder(); + + + for (Role role : selectedRoles) { + assert targetMember != null; + if (canUse(event.getMember(), role)) { + SimpleRoles.removeRole(targetMember, role); + roleMentionBuilder.append(role.getAsMention()).append(" "); + } + } + + event.editMessageEmbeds(new SimpleEmbedBuilder("Remove Roles") + .text("Successfully removed the roles " + roleMentionBuilder.toString() + " from " + targetMember.getAsMention()) + .error() + .build() + ).setComponents().queue(); + } + } + + private static boolean canUse(Member member, Role role) { + List allowedSupporterRoles = new ArrayList(); + allowedSupporterRoles.add(Settings.Roles.verified); + allowedSupporterRoles.add(Settings.Roles.spigot); + allowedSupporterRoles.add(Settings.Roles.builtByBit); + allowedSupporterRoles.add(Settings.Roles.songoda); + allowedSupporterRoles.add(Settings.Roles.polymart); + allowedSupporterRoles.add(Settings.Roles.ultraPermissions); + allowedSupporterRoles.add(Settings.Roles.ultraPunishments); + allowedSupporterRoles.add(Settings.Roles.ultraCustomizer); + allowedSupporterRoles.add(Settings.Roles.ultraRegions); + allowedSupporterRoles.add(Settings.Roles.ultraEconomy); + allowedSupporterRoles.add(Settings.Roles.ultraScoreboards); + allowedSupporterRoles.add(Settings.Roles.ultraMotd); + allowedSupporterRoles.add(Settings.Roles.insaneShops); + allowedSupporterRoles.add(Settings.Roles.insaneVaults); + + if (member.getRoles().contains(SimpleRoles.getRoleById(member.getGuild(), Settings.Roles.supporter))) { + return allowedSupporterRoles.contains(role.getIdLong()); + } + + return member.getPermissions().contains(Permission.ADMINISTRATOR); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/SelfRolesMenu.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/SelfRolesMenu.java new file mode 100644 index 00000000..4b1d421c --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/SelfRolesMenu.java @@ -0,0 +1,155 @@ +package me.techscode.techdiscordbot.actions.menus; + +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.handlers.selectmenu.string.SimpleStringSelectMenu; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.interactions.components.selections.SelectOption; +import net.dv8tion.jda.api.interactions.components.selections.StringSelectInteraction; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class SelfRolesMenu extends SimpleStringSelectMenu { + + public SelfRolesMenu() { + super("selfRolesMenu"); + placeholder("Select the roles you want to get pings for"); + + minMax(0, 6); + + options( + SelectOption.of("Plugin Updates", "pluginUpdates") + .withEmoji(Emoji.fromFormatted("<:Updates:837724632739217418>")) + .withDescription("Get notified when a plugin gets updated"), + SelectOption.of("Announcements", "announcements") + .withEmoji(Emoji.fromFormatted("<:Announcements:837724632655986718>")) + .withDescription("Get notified when a new announcement is made"), + SelectOption.of("Patreon News", "patreonNews") + .withEmoji(Emoji.fromFormatted("<:PatreonNews:873383006520356964>")) + .withDescription("Get notified when a new Patreon news is made"), + SelectOption.of("PluginLab", "pluginLab") + .withEmoji(Emoji.fromFormatted("<:PluginLab:1045068040615772221>")) + .withDescription("Get notified when a new PluginLab is released"), + SelectOption.of("Giveaways", "giveaways") + .withEmoji(Emoji.fromFormatted("<:giveaways:837724632529895486>")) + .withDescription("Get notified when a new giveaway is hosted"), + SelectOption.of("Community", "community") + .withEmoji(Emoji.fromFormatted("<:TechSupport:681682145823293447>")) + .withDescription("Get access to the community channels"), + SelectOption.of("Insane Announcer", "insaneAnnouncer") + .withEmoji(Emoji.fromFormatted("<:InsaneAnnouncer:741465636231970886>")) + .withDescription("Get access to the insane announcer support channel") + ); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + final List options = event.getSelectedOptions(); + + final boolean updates = false; + boolean announcements = false; + boolean patreonNews = false; + boolean pluginLab = false; + boolean giveaways = false; + boolean community = false; + boolean insaneAnnouncer = false; + + + final Role updateRole = SimpleRoles.getRoleById(Objects.requireNonNull(event.getGuild()), Settings.Roles.updates); + + final List addedRoles = new ArrayList<>(); + final List removedRoles = new ArrayList<>(); + + for (final SelectOption option : options) { + if (option.getValue().equals("pluginUpdates") && SimpleRoles.hasRole(getMember(), updateRole)) { + SimpleRoles.removeRole(getMember(), updateRole); + removedRoles.add(updateRole); + } else if (!SimpleRoles.hasRole(getMember(), updateRole)) { + SimpleRoles.addRole(getMember(), updateRole); + addedRoles.add(updateRole); + } + if (option.getValue().equals("announcements")) announcements = true; + if (option.getValue().equals("patreonNews")) patreonNews = true; + if (option.getValue().equals("pluginLab")) pluginLab = true; + if (option.getValue().equals("giveaways")) giveaways = true; + if (option.getValue().equals("community")) community = true; + if (option.getValue().equals("insaneAnnouncer")) insaneAnnouncer = true; + } + + final Role announcementsRole = SimpleRoles.getRoleById(Objects.requireNonNull(event.getGuild()), Settings.Roles.announcements); + if (announcements && SimpleRoles.hasRole(getMember(), announcementsRole)) { + SimpleRoles.removeRole(getMember(), announcementsRole); + removedRoles.add(announcementsRole); + } else if (announcements && !SimpleRoles.hasRole(getMember(), announcementsRole)) { + SimpleRoles.addRole(getMember(), announcementsRole); + addedRoles.add(announcementsRole); + } + + + if (patreonNews) { + final Role role = SimpleRoles.getRoleById(Objects.requireNonNull(event.getGuild()), Settings.Roles.patreonNews); + if (SimpleRoles.hasRole(getMember(), role)) { + SimpleRoles.removeRole(getMember(), role); + removedRoles.add(role); + } else { + SimpleRoles.addRole(getMember(), role); + addedRoles.add(role); + } + } + + if (pluginLab) { + final Role role = SimpleRoles.getRoleById(Objects.requireNonNull(event.getGuild()), Settings.Roles.pluginLab); + if (SimpleRoles.hasRole(getMember(), role)) { + SimpleRoles.removeRole(getMember(), role); + removedRoles.add(role); + } else { + SimpleRoles.addRole(getMember(), role); + addedRoles.add(role); + } + } + + if (giveaways) { + final Role role = SimpleRoles.getRoleById(Objects.requireNonNull(event.getGuild()), Settings.Roles.giveaways); + if (SimpleRoles.hasRole(getMember(), role)) { + SimpleRoles.removeRole(getMember(), role); + removedRoles.add(role); + } else { + SimpleRoles.addRole(getMember(), role); + addedRoles.add(role); + } + } + + if (community) { + if (SimpleRoles.hasRole(getMember(), Settings.Roles.community)) { + SimpleRoles.removeRole(getMember(), Settings.Roles.community); + } else { + SimpleRoles.addRole(getMember(), Settings.Roles.community); + } + } + + if (insaneAnnouncer) { + if (SimpleRoles.hasRole(getMember(), Settings.Roles.insaneAnnouncer)) { + SimpleRoles.removeRole(getMember(), Settings.Roles.insaneAnnouncer); + } else { + SimpleRoles.addRole(getMember(), Settings.Roles.insaneAnnouncer); + } + } + + event.replyEmbeds(new SimpleEmbedBuilder("Roles Updated!") + .text( + "Your roles have successfully been updated!", + "Your roles have either been added or removed upon your selection." + ) + .success().build() + ).setEphemeral(true).queue(); + + + // Get the selected roles from the event and check if the user has these roles. If they do do nothing if they haven't add them. And than remove the roles that the user doesn't have selected. + + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/TicketMenus.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/TicketMenus.java new file mode 100644 index 00000000..690a218a --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/menus/TicketMenus.java @@ -0,0 +1,718 @@ +package me.techscode.techdiscordbot.actions.menus; + +import com.greazi.discordbotfoundation.debug.Debugger; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.handlers.selectmenu.string.SimpleStringSelectMenu; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.model.enums.Plugin; +import me.techscode.techdiscordbot.model.enums.Ticket; +import me.techscode.techdiscordbot.modules.TicketModule; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.interactions.components.selections.SelectOption; +import net.dv8tion.jda.api.interactions.components.selections.StringSelectInteraction; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class TicketMenus { + + public static class TicketMenu extends SimpleStringSelectMenu { + public TicketMenu(@NotNull final Member creator) { + super("Ticket:" + creator.getId()); + placeholder("Select your ticket type"); + minMax(1, 1); + options( + SelectOption.of(Ticket.Category.PLUGIN.getName(), Ticket.Category.PLUGIN.getId()) + .withEmoji(Ticket.Category.PLUGIN.getEmoji()) + .withDescription(Ticket.Category.PLUGIN.getDescription()), + + SelectOption.of(Ticket.Category.PAYMENTS.getName(), Ticket.Category.PAYMENTS.getId()) + .withEmoji(Ticket.Category.PAYMENTS.getEmoji()) + .withDescription(Ticket.Category.PAYMENTS.getDescription()), + + SelectOption.of(Ticket.Category.DEVELOPER.getName(), Ticket.Category.DEVELOPER.getId()) + .withEmoji(Ticket.Category.DEVELOPER.getEmoji()) + .withDescription(Ticket.Category.DEVELOPER.getDescription()), + + SelectOption.of(Ticket.Category.GIVEAWAY.getName(), Ticket.Category.GIVEAWAY.getId()) + .withEmoji(Ticket.Category.GIVEAWAY.getEmoji()) + .withDescription(Ticket.Category.GIVEAWAY.getDescription()), + + SelectOption.of(Ticket.Category.PATREON.getName(), Ticket.Category.PATREON.getId()) + .withEmoji(Ticket.Category.PATREON.getEmoji()) + .withDescription(Ticket.Category.PATREON.getDescription()), + + SelectOption.of(Ticket.Category.OTHER.getName(), Ticket.Category.OTHER.getId()) + .withEmoji(Ticket.Category.OTHER.getEmoji()) + .withDescription(Ticket.Category.OTHER.getDescription()), + + SelectOption.of("Close", "close") + .withEmoji(Emoji.fromUnicode("❌")) + .withDescription("Close the ticket") + ); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + // Get the ID from the modal ID + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("You cannot utilize someone else's menu.").setEphemeral(true).queue(); + return; + } + + final List options = event.getSelectedOptions(); + + event.getMessage().delete().queue(); + + for (final SelectOption option : options) { + switch (option.getValue().toLowerCase()) { + case "plugin" -> { + StringBuilder plugins = new StringBuilder( + "## You haven't bought any plugins yet. You can verify your purchases in <#907349490556616745>\n" + + "This means that you **can't** create tickets for premium plugins." + ); + boolean boughtPlugins = false; + for (Plugin plugin : Plugin.getOwnedPlugins(getMember())) { + if (!boughtPlugins) { + plugins.delete(0, plugins.length()); + boughtPlugins = true; + } + plugins.append(plugin.getEmojiRaw()).append(" ").append(plugin.getName()).append("\n"); + } + event.replyEmbeds(new SimpleEmbedBuilder("📨 Plugin Support") + .text( + "Please select the plugin you need support for.", + "", + "**Plugins you own:**", + plugins.length() == 0 ? "You haven't verified any premium plugins. You can verify your plugins in <#907349490556616745>\n" : plugins.toString(), + "**Free plugins**", + Plugin.INSANE_ANNOUNCER.getEmojiRaw() + " " + Plugin.INSANE_ANNOUNCER.getName() + ) + .build()).setActionRow(new PluginMenu(this.getMember()).build()).queue(); + Debugger.debug("Ticket", "Plugin menu opened"); + Database.TICKETS.setCategory(event.getChannel().getIdLong(), Ticket.Category.PLUGIN); + } + case "payments" -> { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Payments") + .text( + "Please select a sub category.", + "", + "**Sub categories:**", + Ticket.Payment.PAYPAL.getEmojiRaw() + " " + Ticket.Payment.PAYPAL.getName(), + Ticket.Payment.MARKETPLACE.getEmojiRaw() + " " + Ticket.Payment.MARKETPLACE.getName(), + Ticket.Payment.OTHER.getEmojiRaw() + " " + Ticket.Payment.OTHER.getName() + ) + .build()).setActionRow(new PaymentMenu(this.getMember()).build()).queue(); + Debugger.debug("Ticket", "Payment menu opened"); + Database.TICKETS.setCategory(event.getChannel().getIdLong(), Ticket.Category.PAYMENTS); + } + case "developer" -> { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Developer") + .text( + "Please select a sub category.", + "", + "**Sub categories:**", + Ticket.Developer.API.getEmojiRaw() + " " + Ticket.Developer.API.getName(), + Ticket.Developer.PLUGIN.getEmojiRaw() + " " + Ticket.Developer.PLUGIN.getName(), + Ticket.Developer.OTHER.getEmojiRaw() + " " + Ticket.Developer.OTHER.getName() + ) + .build()).setActionRow(new DeveloperMenu(this.getMember()).build()).queue(); + Debugger.debug("Ticket", "Developer menu opened"); + Database.TICKETS.setCategory(event.getChannel().getIdLong(), Ticket.Category.DEVELOPER); + } + case "giveaway" -> { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Giveaways") + .text( + "Please select a sub category.", + "", + "**Sub categories:**", + Ticket.Giveaway.CLAIM.getEmojiRaw() + " " + Ticket.Giveaway.CLAIM.getName(), + Ticket.Giveaway.HOST.getEmojiRaw() + " " + Ticket.Giveaway.HOST.getName() + ) + .build()).setActionRow(new GiveawayMenu(this.getMember()).build()).queue(); + Debugger.debug("Ticket", "Giveaway menu opened"); + Database.TICKETS.setCategory(event.getChannel().getIdLong(), Ticket.Category.GIVEAWAY); + } + case "patreon" -> { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Patreon") + .text( + "Please select a sub category.", + "", + "**Sub categories:**", + Ticket.Patreon.PERKS.getEmojiRaw() + " " + Ticket.Patreon.PERKS.getName(), + Ticket.Patreon.REWARDS.getEmojiRaw() + " " + Ticket.Patreon.REWARDS.getName(), + Ticket.Patreon.OTHER.getEmojiRaw() + " " + Ticket.Patreon.OTHER.getName() + ) + .build()).setActionRow(new PatreonMenu(this.getMember()).build()).queue(); + Debugger.debug("Ticket", "Patreon menu opened"); + Database.TICKETS.setCategory(event.getChannel().getIdLong(), Ticket.Category.PATREON); + } + case "other" -> { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Priority") + .text( + "Now that you have created a ticket you will need to set a priority.", + "The priority only shows the staff team how important the ticket is for you.", + "", + "Note that staff members can change the priority at any time, and without any reason.", + "Please select the priority you want to set for your ticket.", + "", + Ticket.Priority.HIGH.getEmojiRaw() + " **High Priority** - Only be used for critical issues", + Ticket.Priority.MEDIUM.getEmojiRaw() + " **Medium Priority** - For non-critical but important issues", + Ticket.Priority.LOW.getEmojiRaw() + " **Low Priority** - For non-critical issues", + Ticket.Priority.NONE.getEmojiRaw() + " **No Priority** - For matters that are neither essential nor important" + ) + .build()).setActionRow(new PriorityMenu(this.getMember()).build()).queue(); + Debugger.debug("Ticket", "Priority menu opened"); + Database.TICKETS.setCategory(event.getChannel().getIdLong(), Ticket.Category.OTHER); + } + case "close" -> { + TicketModule.ticketClose(event.getMember(), Database.TICKETS.get(event.getChannel().getIdLong()).get(0), event.getTimeCreated().toEpochSecond(), "Ticket creation has been canceled", 30000); + } + default -> { + event.replyEmbeds(new SimpleEmbedBuilder("Ticket ERROR") + .text( + "An error occurred while creating your ticket.", + "Please contact staff for further assistance." + ) + .error().build()).setEphemeral(true).queue(); + Debugger.debug("Ticket", "Unknown option: " + option.getValue()); + } + } + } + this.remove(); + } + } + + public static class PluginMenu extends SimpleStringSelectMenu { + + public PluginMenu(@NotNull final Member member) { + super("TicketPlugin:" + member.getId()); + placeholder("Select the plugin you need support for"); + minMax(1, 1); + + final List selectOptionsList = new ArrayList<>(); + final List memberRoles = member.getRoles(); + + if (memberRoles.contains(Plugin.ULTRA_PERMISSIONS.getRole())) { + selectOptionsList.add(SelectOption.of("Ultra Permissions", Plugin.ULTRA_PERMISSIONS.getId() + "") + .withEmoji(Plugin.ULTRA_PERMISSIONS.getEmoji()) + .withDescription("Create a ticket for Ultra Permissions") + ); + } + + if (memberRoles.contains(Plugin.ULTRA_CUSTOMIZER.getRole())) { + selectOptionsList.add(SelectOption.of("Ultra Customizer", Plugin.ULTRA_CUSTOMIZER.getId() + "") + .withEmoji(Plugin.ULTRA_CUSTOMIZER.getEmoji()) + .withDescription("Create a ticket for Ultra Customizer") + ); + } + + if (memberRoles.contains(Plugin.ULTRA_ECONOMY.getRole())) { + selectOptionsList.add(SelectOption.of("Ultra Economy", Plugin.ULTRA_ECONOMY.getId() + "") + .withEmoji(Plugin.ULTRA_ECONOMY.getEmoji()) + .withDescription("Create a ticket for Ultra Economy") + ); + } + + if (memberRoles.contains(Plugin.ULTRA_PUNISHMENTS.getRole())) { + selectOptionsList.add(SelectOption.of("Ultra Punishments", Plugin.ULTRA_PUNISHMENTS.getId() + "") + .withEmoji(Plugin.ULTRA_PUNISHMENTS.getEmoji()) + .withDescription("Create a ticket for Ultra Punishments") + ); + } + + if (memberRoles.contains(Plugin.ULTRA_REGIONS.getRole())) { + selectOptionsList.add(SelectOption.of("Ultra Regions", Plugin.ULTRA_REGIONS.getId() + "") + .withEmoji(Plugin.ULTRA_REGIONS.getEmoji()) + .withDescription("Create a ticket for Ultra Regions") + ); + } + + if (memberRoles.contains(Plugin.ULTRA_SCOREBOARDS.getRole())) { + selectOptionsList.add(SelectOption.of("Ultra Scoreboards", Plugin.ULTRA_SCOREBOARDS.getId() + "") + .withEmoji(Plugin.ULTRA_SCOREBOARDS.getEmoji()) + .withDescription("Create a ticket for Ultra Scoreboards") + ); + } + + if (memberRoles.contains(Plugin.ULTRA_MOTD.getRole())) { + selectOptionsList.add(SelectOption.of("Ultra Motd", Plugin.ULTRA_MOTD.getId() + "") + .withEmoji(Plugin.ULTRA_MOTD.getEmoji()) + .withDescription("Create a ticket for Ultra Motd") + ); + } + + if (memberRoles.contains(Plugin.INSANE_SHOPS.getRole())) { + selectOptionsList.add(SelectOption.of("Insane Shops", Plugin.INSANE_SHOPS.getId() + "") + .withEmoji(Plugin.INSANE_SHOPS.getEmoji()) + .withDescription("Create a ticket for Insane Shops") + ); + } + + if (memberRoles.contains(Plugin.INSANE_VAULTS.getRole())) { + selectOptionsList.add(SelectOption.of("Insane Vaults", Plugin.INSANE_VAULTS.getId() + "") + .withEmoji(Plugin.INSANE_VAULTS.getEmoji()) + .withDescription("Create a ticket for Insane Vaults") + ); + } + + selectOptionsList.add(SelectOption.of("Insane Announcer", Plugin.INSANE_ANNOUNCER.getId() + "") + .withEmoji(Plugin.INSANE_ANNOUNCER.getEmoji()) + .withDescription("Create a ticket for Insane Announcer") + ); + selectOptionsList.add(SelectOption.of("Back", "back") + .withEmoji(Emoji.fromUnicode("⏮️")) + .withDescription("Go back to the previous menu") + ); + + options(selectOptionsList); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + // Get the ID from the modal ID + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("You cannot utilize someone else's menu.").setEphemeral(true).queue(); + return; + } + + final List options = event.getSelectedOptions(); + + event.getMessage().delete().queue(); + + for (final SelectOption option : options) { + if (option.getValue().equals("back")) { + back(event, getMember()); + this.remove(); + return; + } else { + + Plugin plugin = Plugin.getPluginById(Integer.parseInt(option.getValue())); + assert plugin != null; + Database.TICKETS.setType(event.getChannel().getIdLong(), plugin.toString()); + + if (SimpleRoles.hasRole(getMember(), Settings.Roles.Patreon.patreon)) { + + // Add the priority to the database + Database.TICKETS.setPriority(event.getChannel().getIdLong(), Ticket.Priority.PATREON.toString()); + + // Send the ticket creation message + TicketModule.finishTicketCreation(event.getChannel().asTextChannel(), getMember()); + + return; + } + + event.replyEmbeds(new SimpleEmbedBuilder("Ticket creation (3/3)") + .text( + "Now that you have created a ticket you will need to set a priority.", + "The priority only shows the staff team how important the ticket is for you.", + "", + "Note that staff members can change the priority at any time, and without any reason.", + "Please select the priority you want to set for your ticket.", + "", + Ticket.Priority.HIGH.getEmojiRaw() + " **High Priority** - Only be used for critical issues", + Ticket.Priority.MEDIUM.getEmojiRaw() + " **Medium Priority** - For non-critical but important issues", + Ticket.Priority.LOW.getEmojiRaw() + " **Low Priority** - For non-critical issues", + Ticket.Priority.NONE.getEmojiRaw() + " **No Priority** - For matters that are neither essential nor important" + ) + .build()).setActionRow(new PriorityMenu(this.getMember()).build()).queue(); + } + this.remove(); + } + + } + } + + public static class PaymentMenu extends SimpleStringSelectMenu { + + public PaymentMenu(@NotNull final Member member) { + super("TicketPay:" + member.getId()); + placeholder("Select the payment method you need help with"); + minMax(1, 1); + + final List selectOptionsList = new ArrayList<>(); + + selectOptionsList.add(SelectOption.of("Paypal", Ticket.Payment.PAYPAL.getId().toLowerCase()) + .withEmoji(Ticket.Payment.PAYPAL.getEmoji()) + .withDescription(Ticket.Payment.PAYPAL.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Marketplace", Ticket.Payment.MARKETPLACE.getId().toLowerCase()) + .withEmoji(Ticket.Payment.MARKETPLACE.getEmoji()) + .withDescription(Ticket.Payment.MARKETPLACE.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Other Payment", Ticket.Payment.OTHER.getId().toLowerCase()) + .withEmoji(Ticket.Payment.OTHER.getEmoji()) + .withDescription(Ticket.Payment.OTHER.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Back", "back") + .withEmoji(Emoji.fromUnicode("⏮️")) + .withDescription("Go back to the previous menu") + ); + + options(selectOptionsList); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + // Get the ID from the modal ID + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("You cannot utilize someone else's menu.").setEphemeral(true).queue(); + return; + } + + final List options = event.getSelectedOptions(); + + event.getMessage().delete().queue(); + + for (final SelectOption option : options) { + if (option.getValue().equals("back")) { + back(event, getMember()); + this.remove(); + return; + } else { + + event.replyEmbeds(new SimpleEmbedBuilder("Ticket creation (3/3)") + .text( + "Now that you have created a ticket you will need to set a priority.", + "The priority only shows the staff team how important the ticket is for you.", + "", + "Note that staff members can change the priority at any time, and without any reason.", + "Please select the priority you want to set for your ticket.", + "", + Ticket.Priority.HIGH.getEmojiRaw() + " **High Priority** - Only be used for critical issues", + Ticket.Priority.MEDIUM.getEmojiRaw() + " **Medium Priority** - For non-critical but important issues", + Ticket.Priority.LOW.getEmojiRaw() + " **Low Priority** - For non-critical issues", + Ticket.Priority.NONE.getEmojiRaw() + " **No Priority** - For matters that are neither essential nor important" + ) + .build()).setActionRow(new PriorityMenu(this.getMember()).build()).queue(); + + Database.TICKETS.setType(event.getChannel().getIdLong(), Ticket.Payment.valueOf(option.getValue().toUpperCase()).getId()); + } + this.remove(); + } + + } + } + + public static class DeveloperMenu extends SimpleStringSelectMenu { + + public DeveloperMenu(@NotNull final Member member) { + super("TicketDev:" + member.getId()); + placeholder("Select what kind of help you need"); + minMax(1, 1); + + final List selectOptionsList = new ArrayList<>(); + + selectOptionsList.add(SelectOption.of("API", Ticket.Developer.API.getId()) + .withEmoji(Ticket.Developer.API.getEmoji()) + .withDescription(Ticket.Developer.API.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Plugin", Ticket.Developer.PLUGIN.getId()) + .withEmoji(Ticket.Developer.PLUGIN.getEmoji()) + .withDescription(Ticket.Developer.PLUGIN.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Other", Ticket.Developer.OTHER.getId()) + .withEmoji(Ticket.Developer.OTHER.getEmoji()) + .withDescription(Ticket.Developer.OTHER.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Back", "back") + .withEmoji(Emoji.fromUnicode("⏮️")) + .withDescription("Go back to the previous menu") + ); + + options(selectOptionsList); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + // Get the ID from the modal ID + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("You cannot utilize someone else's menu.").setEphemeral(true).queue(); + return; + } + + final List options = event.getSelectedOptions(); + + event.getMessage().delete().queue(); + + for (final SelectOption option : options) { + if (option.getValue().equals("back")) { + back(event, getMember()); + this.remove(); + return; + } else { + + event.replyEmbeds(new SimpleEmbedBuilder("Ticket creation (3/3)") + .text( + "Now that you have created a ticket you will need to set a priority.", + "The priority only shows the staff team how important the ticket is for you.", + "", + "Note that staff members can change the priority at any time, and without any reason.", + "Please select the priority you want to set for your ticket.", + "", + Ticket.Priority.HIGH.getEmojiRaw() + " **High Priority** - Only be used for critical issues", + Ticket.Priority.MEDIUM.getEmojiRaw() + " **Medium Priority** - For non-critical but important issues", + Ticket.Priority.LOW.getEmojiRaw() + " **Low Priority** - For non-critical issues", + Ticket.Priority.NONE.getEmojiRaw() + " **No Priority** - For matters that are neither essential nor important" + ) + .build()).setActionRow(new PriorityMenu(this.getMember()).build()).queue(); + + Database.TICKETS.setType(event.getChannel().getIdLong(), Ticket.Developer.valueOf(option.getValue().toUpperCase()).getId()); + } + this.remove(); + } + + } + } + + public static class GiveawayMenu extends SimpleStringSelectMenu { + + public GiveawayMenu(@NotNull final Member member) { + super("TicketGiveaway:" + member.getId()); + placeholder("Claim or host a giveaway"); + minMax(1, 1); + + final List selectOptionsList = new ArrayList<>(); + + selectOptionsList.add(SelectOption.of("Claim", Ticket.Giveaway.CLAIM.getId()) + .withEmoji(Ticket.Giveaway.CLAIM.getEmoji()) + .withDescription(Ticket.Giveaway.CLAIM.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Host", Ticket.Giveaway.HOST.getId()) + .withEmoji(Ticket.Giveaway.HOST.getEmoji()) + .withDescription(Ticket.Giveaway.HOST.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Back", "back") + .withEmoji(Emoji.fromUnicode("⏮️")) + .withDescription("Go back to the previous menu") + ); + + options(selectOptionsList); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + // Get the ID from the modal ID + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("You cannot utilize someone else's menu.").setEphemeral(true).queue(); + return; + } + + final List options = event.getSelectedOptions(); + + event.getMessage().delete().queue(); + + for (final SelectOption option : options) { + if (option.getValue().equals("back")) { + back(event, getMember()); + this.remove(); + return; + } else { + + event.replyEmbeds(new SimpleEmbedBuilder("Ticket creation (3/3)") + .text( + "Now that you have created a ticket you will need to set a priority.", + "The priority only shows the staff team how important the ticket is for you.", + "", + "Note that staff members can change the priority at any time, and without any reason.", + "Please select the priority you want to set for your ticket.", + "", + Ticket.Priority.HIGH.getEmojiRaw() + " **High Priority** - Only be used for critical issues", + Ticket.Priority.MEDIUM.getEmojiRaw() + " **Medium Priority** - For non-critical but important issues", + Ticket.Priority.LOW.getEmojiRaw() + " **Low Priority** - For non-critical issues", + Ticket.Priority.NONE.getEmojiRaw() + " **No Priority** - For matters that are neither essential nor important" + ) + .build()).setActionRow(new PriorityMenu(this.getMember()).build()).queue(); + + Database.TICKETS.setType(event.getChannel().getIdLong(), Ticket.Giveaway.valueOf(option.getValue().toUpperCase()).getId()); + } + this.remove(); + } + + } + } + + public static class PatreonMenu extends SimpleStringSelectMenu { + + public PatreonMenu(@NotNull final Member member) { + super("TicketPatreon:" + member.getId()); + placeholder("Help for our Patreon program"); + minMax(1, 1); + + final List selectOptionsList = new ArrayList<>(); + + selectOptionsList.add(SelectOption.of("Perks", Ticket.Patreon.PERKS.getId()) + .withEmoji(Ticket.Patreon.PERKS.getEmoji()) + .withDescription(Ticket.Patreon.PERKS.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Rewards", Ticket.Patreon.REWARDS.getId()) + .withEmoji(Ticket.Patreon.REWARDS.getEmoji()) + .withDescription(Ticket.Patreon.REWARDS.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Other", Ticket.Patreon.OTHER.getId()) + .withEmoji(Ticket.Patreon.OTHER.getEmoji()) + .withDescription(Ticket.Patreon.OTHER.getDescription()) + ); + selectOptionsList.add(SelectOption.of("Back", "back") + .withEmoji(Emoji.fromUnicode("⏮️")) + .withDescription("Go back to the previous menu") + ); + + options(selectOptionsList); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + // Get the ID from the modal ID + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("You cannot utilize someone else's menu.").setEphemeral(true).queue(); + return; + } + + final List options = event.getSelectedOptions(); + + event.getMessage().delete().queue(); + + for (final SelectOption option : options) { + if (option.getValue().equals("back")) { + back(event, getMember()); + this.remove(); + return; + } else { + + event.replyEmbeds(new SimpleEmbedBuilder("Ticket creation (3/3)") + .text( + "Now that you have created a ticket you will need to set a priority.", + "The priority only shows the staff team how important the ticket is for you.", + "", + "Note that staff members can change the priority at any time, and without any reason.", + "Please select the priority you want to set for your ticket.", + "", + Ticket.Priority.HIGH.getEmojiRaw() + " **High Priority** - Only be used for critical issues", + Ticket.Priority.MEDIUM.getEmojiRaw() + " **Medium Priority** - For non-critical but important issues", + Ticket.Priority.LOW.getEmojiRaw() + " **Low Priority** - For non-critical issues", + Ticket.Priority.NONE.getEmojiRaw() + " **No Priority** - For matters that are neither essential nor important" + ) + .build()).setActionRow(new PriorityMenu(this.getMember()).build()).queue(); + + Database.TICKETS.setType(event.getChannel().getIdLong(), Ticket.Patreon.valueOf(option.getValue().toUpperCase()).getId()); + } + this.remove(); + } + + } + } + + public static class PriorityMenu extends SimpleStringSelectMenu { + public PriorityMenu(@NotNull final Member member) { + super("TicketPriority:" + member.getId()); + placeholder("Select a priority"); + minMax(1, 1); + options( + SelectOption.of("High Priority", "high") + .withEmoji(Emoji.fromFormatted("<:high_priority:694648884332331008>")) + .withDescription("Only be used for critical issues"), + SelectOption.of("Medium Priority", "medium") + .withEmoji(Emoji.fromFormatted("<:medium_priority:694648883980009593>")) + .withDescription("For non-critical but important issues"), + SelectOption.of("Low Priority", "low") + .withEmoji(Emoji.fromFormatted("<:low_priority:694648884353433601>")) + .withDescription("For non-critical issues"), + SelectOption.of("No Priority", "none") + .withEmoji(Emoji.fromFormatted("<:offline:496493395187990538>")) + .withDescription("For matters that are neither essential nor important") + ); + } + + @Override + protected void onMenuInteract(final StringSelectInteraction event) { + // Get the ID from the modal ID + final String target_id = Objects.requireNonNull(event.getSelectMenu().getId()).split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("You cannot utilize someone else's menu.").setEphemeral(true).queue(); + return; + } + + // Get the options that have been selected + final List options = event.getSelectedOptions(); + + // Delete the old message + event.getMessage().delete().queue(); + + // Set the priority to default none + Ticket.Priority priority = Ticket.Priority.NONE; + + // Get the priority + for (final SelectOption option : options) { + switch (option.getValue()) { + case "high": + priority = Ticket.Priority.HIGH; + break; + case "medium": + priority = Ticket.Priority.MEDIUM; + break; + case "low": + priority = Ticket.Priority.LOW; + break; + case "no": + priority = Ticket.Priority.NONE; + break; + } + } + + // Add the priority to the database + Database.TICKETS.setPriority(event.getChannel().getIdLong(), priority.toString()); + + // Send the ticket creation message + TicketModule.finishTicketCreation(event.getChannel().asTextChannel(), getMember()); + + this.remove(); + } + } + + private static void back(StringSelectInteraction event, Member member) { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket") + .text( + "Please select what kind of ticket you want to create.", + "", + "**Available categories:**", + Ticket.Category.PLUGIN.getEmojiRaw() + " " + Ticket.Category.PLUGIN.getName() + " - " + Ticket.Category.PLUGIN.getDescription(), + Ticket.Category.PAYMENTS.getEmojiRaw() + " " + Ticket.Category.PAYMENTS.getName() + " - " + Ticket.Category.PAYMENTS.getDescription(), + Ticket.Category.DEVELOPER.getEmojiRaw() + " " + Ticket.Category.DEVELOPER.getName() + " - " + Ticket.Category.DEVELOPER.getDescription(), + Ticket.Category.GIVEAWAY.getEmojiRaw() + " " + Ticket.Category.GIVEAWAY.getName() + " - " + Ticket.Category.GIVEAWAY.getDescription(), + Ticket.Category.PATREON.getEmojiRaw() + " " + Ticket.Category.PATREON.getName() + " - " + Ticket.Category.PATREON.getDescription(), + Ticket.Category.OTHER.getEmojiRaw() + " " + Ticket.Category.OTHER.getName() + " - " + Ticket.Category.OTHER.getDescription(), + "", + "*Please keep in mind that in order to access support for any premium resource, you must first verify your purchase.*" + ) + .build() + ).setActionRow(new TicketMenu(member).build()).queue(); + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ApplicationModal.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ApplicationModal.java new file mode 100644 index 00000000..cab8952c --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ApplicationModal.java @@ -0,0 +1,371 @@ +package me.techscode.techdiscordbot.actions.modals; + +import com.greazi.discordbotfoundation.handlers.modals.SimpleModal; +import com.greazi.discordbotfoundation.handlers.modals.SimpleTextInput; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.actions.buttons.ApplyButton; +import me.techscode.techdiscordbot.actions.menus.ApplyMenu; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.model.enums.Application; +import me.techscode.techdiscordbot.modules.ApplyModule; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import org.jetbrains.annotations.NotNull; + +public class ApplicationModal { + + public static class GeneralQuestions extends SimpleModal { + + public GeneralQuestions(@NotNull Member member) { + super("AGQ-" + member.getIdLong()); + mainGuildOnly(); + title("General Application Questions"); + + final SimpleTextInput nameQuestion = new SimpleTextInput("nameage", "What is your name and age?"); + nameQuestion.setRequired(); + nameQuestion.setParagraph(); + + final SimpleTextInput timezoneQuestion = new SimpleTextInput("timezone", "What is your timezone?"); + timezoneQuestion.setRequired(); + timezoneQuestion.setParagraph(); + + final SimpleTextInput availableTimeQuestion = new SimpleTextInput("time", "Available time per week?"); + availableTimeQuestion.setRequired(); + availableTimeQuestion.setParagraph(); + + final SimpleTextInput whyQuestion = new SimpleTextInput("why", "Why do you want to join?"); + whyQuestion.setRequired(); + whyQuestion.setParagraph(); + + final SimpleTextInput proConQuestion = new SimpleTextInput("procon", "Pro's and Con's"); + proConQuestion.setRequired(); + proConQuestion.setParagraph(); + + textInputs(nameQuestion, timezoneQuestion, availableTimeQuestion, whyQuestion, proConQuestion); + } + + @Override + protected void onModalInteract(@NotNull ModalInteractionEvent event) { + + event.getMessage().delete().queue(); + + final String nameage = event.getValue("nameage").getAsString(); + final String timezone = event.getValue("timezone").getAsString(); + final String time = event.getValue("time").getAsString(); + final String why = event.getValue("why").getAsString(); + final String procon = event.getValue("procon").getAsString(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("General Application Questions") + .field("What is your name and age?", nameage, false) + .field("What is your timezone?", timezone, false) + .field("Available time per week?", time, false) + .field("Why do you want to join?", why, false) + .field("Pro's and Con's", procon, false) + .build()).queue(); + + event.replyEmbeds(new SimpleEmbedBuilder("Which position?") + .text("Now that we know a bit more about you, which position would you like to apply for?") + .field("Support", "Help people with their problems", false) + .field("Developer", "Help our developer team", false) + .field("Marketing", "Help our marketing team, maintain our socials and more", false) + .field("Translator", "Help our team by translating our plugins", false) + .build() + ).addActionRow(new ApplyMenu(getMember()).build()).queue(); + + } + } + + public static class Support extends SimpleModal { + + public Support(@NotNull Member member) { + super("ASQ-" + member.getIdLong()); + mainGuildOnly(); + title("Support Application Questions"); + + final SimpleTextInput pastQuestion = new SimpleTextInput("past", "Did you help people in the past?"); + pastQuestion.setRequired(); + pastQuestion.setParagraph(); + + final SimpleTextInput skillQuestion = new SimpleTextInput("skill", "What plugin are you most skilled in?"); + skillQuestion.setRequired(); + skillQuestion.setParagraph(); + + final SimpleTextInput micQuestion = new SimpleTextInput("microphone", "Do you have a microphone?"); + micQuestion.setRequired(); + micQuestion.setParagraph(); + + final SimpleTextInput whyQuestion = new SimpleTextInput("why", "Why should we choose you?"); + whyQuestion.setRequired(); + whyQuestion.setParagraph(); + + final SimpleTextInput otherQuestion = new SimpleTextInput("other", "Other"); + otherQuestion.setRequired(); + otherQuestion.setParagraph(); + + textInputs(pastQuestion, skillQuestion, micQuestion, whyQuestion, otherQuestion); + + this.remove(); + } + + @Override + protected void onModalInteract(@NotNull ModalInteractionEvent event) { + + event.getMessage().delete().queue(); + event.reply("Success!").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + + final String past = event.getValue("past").getAsString(); + final String skill = event.getValue("skill").getAsString(); + final String mic = event.getValue("microphone").getAsString(); + final String why = event.getValue("why").getAsString(); + final String other = event.getValue("other").getAsString(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Support Application Questions") + .field("Did you help people in the past?", past, false) + .field("What plugin are you most skilled in?", skill, false) + .field("Do you have a microphone?", mic, false) + .field("Why should we choose you?", why, false) + .field("Other", other, false) + .build()).queue(); + + ApplyModule.finishApplicationCreation(event.getChannel().asTextChannel(), getMember()); + + this.remove(); + } + } + + public static class Developer extends SimpleModal { + + public Developer(@NotNull Member member) { + super("ADQ-" + member.getIdLong()); + mainGuildOnly(); + title("Developer Application Questions"); + + final SimpleTextInput langQuestion = new SimpleTextInput("lang", "What program languages do you know?"); + langQuestion.setRequired(); + langQuestion.setParagraph(); + + final SimpleTextInput timeQuestion = new SimpleTextInput("time", "For how long have you been developing?"); + timeQuestion.setRequired(); + timeQuestion.setParagraph(); + + final SimpleTextInput projectQuestion = new SimpleTextInput("projectrun", "Do you know how to run a project?"); + projectQuestion.setRequired(); + projectQuestion.setParagraph(); + + final SimpleTextInput gitQuestion = new SimpleTextInput("git", "Do you have a GitHub profile?"); + gitQuestion.setRequired(); + gitQuestion.setParagraph(); + + final SimpleTextInput ndaQuestion = new SimpleTextInput("nda", "Would you sign an NDA?"); + ndaQuestion.setRequired(); + ndaQuestion.setParagraph(); + + textInputs(langQuestion, timeQuestion, projectQuestion, gitQuestion, ndaQuestion); + } + + @Override + protected void onModalInteract(@NotNull ModalInteractionEvent event) { + + event.getMessage().delete().queue(); + event.reply("Success!").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + + final String lang = event.getValue("lang").getAsString(); + final String time = event.getValue("time").getAsString(); + final String project = event.getValue("projectrun").getAsString(); + final String git = event.getValue("git").getAsString(); + final String nda = event.getValue("nda").getAsString(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Developer Application Questions") + .field("What program languages do you know?", lang, false) + .field("For how long have you been developing?", time, false) + .field("Do you know how to run a project?", project, false) + .field("Do you have a GitHub profile?", git, false) + .field("Would you sign an NDA?", nda, false) + .build()).queue(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Final Questions") + .text("These are the final questions for your application. Please answer them as good as possible.") + .field("Do you have a microphone?", "Do you have a microphone? If so, are you comfortable to get in a voice chat?", false) + .field("Why should we choose you?", "Why should we choose you over other applicants?", false) + .field("Other", "Feel free to enter any other information you want to share with us.", false) + .build() + ).addActionRow(new ApplyButton.ExitQuestions(getMember()).build()).queue(); + + this.remove(); + } + } + + public static class Marketing extends SimpleModal { + + public Marketing(@NotNull Member member) { + super("AMQ-" + member.getIdLong()); + mainGuildOnly(); + title("Marketing Application Questions"); + + final SimpleTextInput expectation = new SimpleTextInput("expectation", "What do you expect?"); + expectation.setRequired(); + expectation.setParagraph(); + + final SimpleTextInput section = new SimpleTextInput("section", "Which section do you prefer?"); + section.setRequired(); + section.setParagraph(); + + final SimpleTextInput experience = new SimpleTextInput("experience", "What is your experience?"); + experience.setRequired(); + experience.setParagraph(); + + final SimpleTextInput graduation = new SimpleTextInput("graduation", "Do you have a graduation?"); + graduation.setRequired(); + graduation.setParagraph(); + + final SimpleTextInput design = new SimpleTextInput("design", "Can you use designer programs?"); + design.setRequired(); + design.setParagraph(); + + textInputs(expectation, section, experience, graduation, design); + } + + @Override + protected void onModalInteract(@NotNull ModalInteractionEvent event) { + + event.getMessage().delete().queue(); + event.reply("Success!").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + + final String expectation = event.getValue("expectation").getAsString(); + final String section = event.getValue("section").getAsString(); + final String experience = event.getValue("experience").getAsString(); + final String graduation = event.getValue("graduation").getAsString(); + final String design = event.getValue("design").getAsString(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Marketing Application Questions") + .field("What do you expect?", expectation, false) + .field("Which section do you prefer?", section, false) + .field("What is your experience?", experience, false) + .field("Do you have a graduation?", graduation, false) + .field("Can you use designer programs?", design, false) + .build()).queue(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Final Questions") + .text("These are the final questions for your application. Please answer them as good as possible.") + .field("Do you have a microphone?", "Do you have a microphone? If so, are you comfortable to get in a voice chat?", false) + .field("Why should we choose you?", "Why should we choose you over other applicants?", false) + .field("Other", "Feel free to enter any other information you want to share with us.", false) + .build() + ).addActionRow(new ApplyButton.ExitQuestions(getMember()).build()).queue(); + + this.remove(); + } + } + + public static class CommunityHelper extends SimpleModal { + + public CommunityHelper(@NotNull Member member) { + super("ACHQ-" + member.getIdLong()); + mainGuildOnly(); + title("Community Helper Application Questions"); + + final SimpleTextInput language = new SimpleTextInput("lang", "What languages do you speak/write?"); + language.setRequired(); + language.setParagraph(); + + final SimpleTextInput git = new SimpleTextInput("git", "Do you have a GitHub profile?"); + git.setRequired(); + git.setParagraph(); + + final SimpleTextInput microphone = new SimpleTextInput("microphone", "Do you have a microphone?"); + microphone.setRequired(); + microphone.setParagraph(); + + final SimpleTextInput why = new SimpleTextInput("why", "Why should we choose you?"); + why.setRequired(); + why.setParagraph(); + + final SimpleTextInput other = new SimpleTextInput("other", "Other"); + other.setRequired(); + other.setParagraph(); + + textInputs(language, git, microphone, why, other); + } + + @Override + protected void onModalInteract(@NotNull ModalInteractionEvent event) { + + event.getMessage().delete().queue(); + event.reply("Success!").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + + final String language = event.getValue("lang").getAsString(); + final String git = event.getValue("git").getAsString(); + final String microphone = event.getValue("microphone").getAsString(); + final String why = event.getValue("why").getAsString(); + final String other = event.getValue("other").getAsString(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Community Helper Application Questions") + .field("What languages do you speak/write?", language, false) + .field("Do you have a GitHub profile?", git, false) + .field("Do you have a microphone?", microphone, false) + .field("Why should we choose you?", why, false) + .field("Other", other, false) + .build()).queue(); + + ApplyModule.finishApplicationCreation(event.getChannel().asTextChannel(), getMember()); + + this.remove(); + } + } + + public static class ExitQuestions extends SimpleModal { + + public ExitQuestions(@NotNull Member member) { + super("AEQ-" + member.getIdLong()); + mainGuildOnly(); + title("Final Application Questions"); + + final SimpleTextInput microphone = new SimpleTextInput("microphone", "Do you have a microphone?"); + microphone.setRequired(); + microphone.setParagraph(); + + final SimpleTextInput why = new SimpleTextInput("why", "Why should we choose you?"); + why.setRequired(); + why.setParagraph(); + + final SimpleTextInput other = new SimpleTextInput("other", "Other"); + other.setRequired(); + other.setParagraph(); + + textInputs(microphone, why, other); + } + + @Override + protected void onModalInteract(@NotNull ModalInteractionEvent event) { + + event.getMessage().delete().queue(); + event.reply("Success!").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + + final String microphone = event.getValue("microphone").getAsString(); + final String why = event.getValue("why").getAsString(); + final String other = event.getValue("other").getAsString(); + + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Community Helper Application Questions") + .field("Do you have a microphone?", microphone, false) + .field("Why should we choose you?", why, false) + .field("Other", other, false) + .build()).queue(); + + if (Database.APPLICATIONSTable.get(event.getChannel().getIdLong()).get(0).getCategory() == Application.Position.MARKETING) { + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Making an announcement") + .text("Now that you have filled in the application, we would like to see how you would make an announcement with the following information.", + "", + "We are going to release a new plugin in the up coming week called Ultra Economy. There has been asked to make an announcement about this plugin.", + "", + "The plugin will be released next week and will be available on SpigotMC. The plugin will be €10,-- and will be available for preorder first for a week. After that, the plugin will be released for everyone." + ) + .build() + ).queue(); + } + + ApplyModule.finishApplicationCreation(event.getChannel().asTextChannel(), getMember()); + + this.remove(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ShutdownModal.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ShutdownModal.java new file mode 100644 index 00000000..fbcc2216 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/ShutdownModal.java @@ -0,0 +1,61 @@ +package me.techscode.techdiscordbot.actions.modals; + +import com.greazi.discordbotfoundation.handlers.modals.SimpleModal; +import com.greazi.discordbotfoundation.handlers.modals.SimpleTextInput; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import org.jetbrains.annotations.NotNull; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.Objects; + +public class ShutdownModal extends SimpleModal { + + public ShutdownModal(final String discord_id) { + super("Shutdown:" + discord_id); + mainGuildOnly(); + title("Confirm Shutdown"); + + final SimpleTextInput confirmQuestion = new SimpleTextInput("confirm", "Type in \"Confirm\" to confirm the shutdown."); + confirmQuestion.setRequired(); + confirmQuestion.setMinMaxLength(7, 7); + + textInputs(confirmQuestion); + } + + /** + * The execution once the modal has been submitted + * + * @param event ModalInteractionEvent + */ + @Override + protected void onModalInteract(@NotNull final ModalInteractionEvent event) { + // Get the user and member from the event + final User user = event.getUser(); + + // Get the target ID of the event before doing anything else + final String target_id = event.getModalId().split(":")[1]; + + // Check if the member is the person who requested the ticket + if (!user.getId().equals(target_id)) { + event.reply("You can't fill in a modal that is meant for someone else").setEphemeral(true).queue(); + return; + } + + if (!Objects.requireNonNull(event.getValue("confirm")).getAsString().equals("CONFIRM")) { + event.reply("You didn't type in \"Confirm\"!").setEphemeral(true).queue(); + return; + } + + event.replyEmbeds(new SimpleEmbedBuilder("Shutdown") + .text( + "Shutting down...", + "Thank you for using Tech's Code Discord Bot!" + ) + .build()).setEphemeral(true).queue(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/TicketModal.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/TicketModal.java new file mode 100644 index 00000000..07ecf6df --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/TicketModal.java @@ -0,0 +1,64 @@ +package me.techscode.techdiscordbot.actions.modals; + +import com.greazi.discordbotfoundation.handlers.modals.SimpleModal; +import com.greazi.discordbotfoundation.handlers.modals.SimpleTextInput; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import org.jetbrains.annotations.NotNull; + +public class TicketModal extends SimpleModal { + + /** + * Set the modal details + */ + public TicketModal(final String discord_id, final String plugin) { + super("Ticket:" + discord_id + ":" + plugin); + mainGuildOnly(); + title("Ticket | " + plugin); + + final SimpleTextInput supportQuestion = new SimpleTextInput("question", "Your support question"); + supportQuestion.setRequired(); + supportQuestion.setParagraph(); + + textInputs(supportQuestion); + } + + /** + * The execution once the modal has been submitted + * + * @param event ModalInteractionEvent + */ + @Override + protected void onModalInteract(@NotNull final ModalInteractionEvent event) { + // Get the user and member from the event + final User user = event.getUser(); + final Member member = event.getMember(); + + // Get the target ID of the event before doing anything else + final String target_id = event.getModalId().split(":")[1]; + + // Check if the member is the person who requested the ticket + if (!user.getId().equals(target_id)) { + event.reply("You can't fill in a modal that is meant for someone else").setEphemeral(true).queue(); + return; + } + + // Create the loading embed + final MessageEmbed embed = new SimpleEmbedBuilder("Ticket") + .text("Creating a new ticket for you...") + .thumbnail("https://i.imgur.com/9TETTf5.gif") + .build(); + + // Message method, so we can edit the message later on + event.replyEmbeds(embed).setEphemeral(true).queue(message -> { + + // Get the rest of the information plugin and support question + final int plugin = Integer.parseInt(event.getModalId().split(":")[2]); + final String supportQuestion = event.getValue("question").getAsString(); + + }); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationModal.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationModal.java new file mode 100644 index 00000000..a1010d8a --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationModal.java @@ -0,0 +1,192 @@ +package me.techscode.techdiscordbot.actions.modals; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.handlers.modals.SimpleModal; +import com.greazi.discordbotfoundation.handlers.modals.SimpleTextInput; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.database.entities.SqlTicket; +import me.techscode.techdiscordbot.model.enums.Marketplace; +import me.techscode.techdiscordbot.model.enums.Ticket; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +/** + * The Verification Modal + */ +public class VerificationModal extends SimpleModal { + + /** + * Set the modal details + */ + public VerificationModal(final String discord_id, final Marketplace marketplace) { + super("Verification:" + discord_id + ":" + marketplace.getId()); + mainGuildOnly(); + title("Verification | " + marketplace.getName()); + + final SimpleTextInput emailInput = new SimpleTextInput("email", "Paypal Email address"); + emailInput.setRequired(); + + final SimpleTextInput transactionInput = new SimpleTextInput("transaction", "Transaction ID (Only 1)"); + transactionInput.setRequired(); + transactionInput.setMinMaxLength(17, 19); + + final SimpleTextInput marketplaceInput = new SimpleTextInput("link", "Marketplace profile link"); + marketplaceInput.setRequired(); + marketplaceInput.setMinMaxLength(35, 100); + + textInputs(emailInput, transactionInput, marketplaceInput); + + // Remove the button with this.remove() after 10 minutes of creation of the button + new Thread(() -> { + try { + Thread.sleep(600000); + this.remove(); + } catch (InterruptedException e) { + Common.throwError(e, "Error while removing button"); + } + }).start(); + } + + /** + * The execution once the modal has been submitted + * + * @param event ModalInteractionEvent + */ + @Override + protected void onModalInteract(@NotNull final ModalInteractionEvent event) { + + // Get the ID from the modal ID + final String target_id = event.getModalId().split(":")[1]; + + // Check if the member is the person who wants to verify + if (!this.getMember().getId().equals(target_id)) { + event.reply("Something is going honorably wrong! Please try to verify your purchase again.").setEphemeral(true).queue(); + return; + } + + // Get the input values + final String email = event.getValue("email").getAsString(); + final String transaction = event.getValue("transaction").getAsString(); + final String link = event.getValue("link").getAsString(); + + Guild guild = event.getGuild(); + Member owner = event.getMember(); + + // Permissions list for the ticket channel + final List permissions = new ArrayList<>( + Arrays.asList( + Permission.VIEW_CHANNEL, + Permission.MESSAGE_HISTORY, + Permission.MESSAGE_SEND, + Permission.MESSAGE_ATTACH_FILES, + Permission.MESSAGE_EMBED_LINKS, + Permission.MESSAGE_ADD_REACTION, + Permission.MANAGE_EMOJIS_AND_STICKERS + ) + ); + + // Get the members name if the members name can't be gathered it will use the user's ID + final String memberName; + if (Objects.equals(owner.getNickname(), "") || owner.getNickname() == null) { + if (owner.getEffectiveName().equals("")) { + memberName = owner.getUser().getId(); + } else { + owner.getEffectiveName(); + memberName = owner.getEffectiveName(); + } + } else { + memberName = owner.getNickname(); + } + + // Get some settings from the settings file + final Category category = guild.getCategoryById("1168185109543931964"); + final long staffRole = Settings.Roles.support; + + // Create the application channel for the member + guild.createTextChannel("verification-" + memberName, category) + .addPermissionOverride(guild.getPublicRole(), null, permissions) + // Add staff permissions + .addRolePermissionOverride(staffRole, permissions, null) + // Add member permissions + .addMemberPermissionOverride(owner.getIdLong(), permissions, Collections.singleton(Permission.MESSAGE_SEND)) + .queue(channel -> { + + channel.sendMessageEmbeds(new SimpleEmbedBuilder("📨 Ticket") + .text( + "Thank you for your verification request!", + "", + "Please wait for a staff member to respond to your ticket.", + "", + "**Please note that this process can take up to 24 hours.**", + "", + "Email: `" + email + "`", + "Transaction ID: `" + transaction + "`", + "Marketplace: `" + link + "`" + ) + .build() + ).queue(); + + new SqlTicket(this.getUser().getIdLong(), channel.getIdLong(), channel.getTimeCreated().toEpochSecond(), Ticket.Category.PAYMENTS.getId(), Ticket.Payment.VERIFICATION.getId(), Ticket.Priority.HIGH.getId()).save(); + + event.replyEmbeds(new SimpleEmbedBuilder("Verification Created") + .text("Your verification ticket has been created! Please wait for a staff member to respond to your ticket.", + "", + "Your verification request: " + channel.getAsMention() + ) + .build()).setEphemeral(true).queue(); + + channel.sendMessage("<@&" + Settings.Roles.support + ">").queue(); + }); + + /* + // Set up the loading embed. + final MessageEmbed embed = new SimpleEmbedBuilder("Verification") + .text("Verifying your details...") + .thumbnail("https://i.imgur.com/jcuD6gb.gif") + .build(); + + // get the values from the modal ID + final Marketplace marketplace = Marketplace.getFromId(Integer.parseInt(event.getModalId().split(":")[2])); + + /*event.replyEmbeds(new SimpleEmbedBuilder("Verification") + .text( + "Thank you for filling in the form.", + "", + "We will verify your purchase as soon as possible.", + "", + "*Please note that this process can take up to 24 hours.*", + "*Also note that if the transaction ID does not match the email address, the verification will be denied.*" + ).success().build()).setEphemeral(true).queue(); + + event.getGuild().getTextChannelById(Settings.Modules.Verification.manualVerification).sendMessageEmbeds( + new SimpleEmbedBuilder("Verification") + .text("A manual verification request has been made by " + getMember().getAsMention() + "!") + .field("User", getMember().getAsMention() + " (" + getMember().getId() + ")", true) + .field("Marketplace", Marketplace.getNamed(marketplace), true) + .field("Profile link", link, true) + .field("Transaction ID", transaction, true) + .field("E-mail", email, false) + .build() + ).queue();*/ + + /*final List linkComponents = List.of(link.split("/")); + final int marketplaceId = Integer.parseInt(linkComponents.get(linkComponents.size() - 1).split("\\.")[1]); + + Debugger.debug("Verification", "Marketplace ID: " + marketplaceId); + + // !!! DISABLED !!! due to the fact that the API is not yet ready + // Send the loading embed and verify the purchase + event.replyEmbeds(embed).setEphemeral(true).queue(message -> { + if (Paypal.verify(this.getMember(), message, email, marketplaceId, transaction, marketplace)) { + Paypal.getPurchases(message, this.getMember(), email, marketplace, marketplaceId); + } + });*/ + } +} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationPreModal.java b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationPreModal.java new file mode 100644 index 00000000..70054dd5 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/actions/modals/VerificationPreModal.java @@ -0,0 +1,107 @@ +package me.techscode.techdiscordbot.actions.modals; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.handlers.modals.SimpleModal; +import com.greazi.discordbotfoundation.handlers.modals.SimpleTextInput; +import com.greazi.discordbotfoundation.utils.RandomGenerator; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.model.enums.Marketplace; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.MessageEmbed; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.ModalInteractionEvent; +import org.jetbrains.annotations.NotNull; + +public class VerificationPreModal extends SimpleModal { + + /** + * Set the modal details + */ + public VerificationPreModal(final String discord_id, final Marketplace marketplace) { + super("VPR:" + discord_id + ":" + marketplace.getId()); + mainGuildOnly(); + title("Verification | " + marketplace.getName()); + + final SimpleTextInput link = new SimpleTextInput("link", "Marketplace profile link"); + link.setRequired(); + + final SimpleTextInput images = new SimpleTextInput("images", "Bought plugins list (images)"); + images.setRequired(); + images.setParagraph(); + images.setPlaceholder("Add your images to a system like Imgur and paste the links here"); + + textInputs(link, images); + + // Remove the button with this.remove() after 10 minutes of creation of the button + new Thread(() -> { + try { + Thread.sleep(600000); + this.remove(); + } catch (InterruptedException e) { + Common.throwError(e, "Error while removing button"); + } + }).start(); + } + + /** + * The execution once the modal has been submitted + * + * @param event ModalInteractionEvent + */ + @Override + protected void onModalInteract(@NotNull final ModalInteractionEvent event) { + // Get static methods + final User user = event.getUser(); + final Member member = event.getMember(); + + // Get the ID from the modal ID + final String target_id = event.getModalId().split(":")[1]; + + // Check if the member is the person who wants to verify + if (!user.getId().equals(target_id)) { + event.reply("Something is going honorably wrong! Please try to verify your purchase again.").setEphemeral(true).queue(); + return; + } + + final String code = RandomGenerator.string(16); + + // Set up the loading embed. + final MessageEmbed embed = new SimpleEmbedBuilder("Verification") + .text( + "Hi there " + member.getAsMention() + ",", + "", + "Before we can verify your purchase, we need to make sure you are the owner of that account.", + "Please make a post on your marketplace profile with the following message:", + "`TechVerification." + code + "`", + "", + "Thank you for filling in the form! We will review your purchase and get back to you as soon as possible", + "When your purchase has been reviewed, you will receive a DM from the bot or a mention in <#" + Settings.Modules.Verification.pingChannel + ">" + ).build(); + + // get the values from the modal ID + String marketplace_id = event.getModalId().split(":")[2]; + final Marketplace marketplace = Marketplace.getFromId(marketplace_id); + + // Get the input values + final String link = event.getValue("link").getAsString(); + final String images = event.getValue("images").getAsString(); + + + // Send the loading embed and verify the purchase + event.replyEmbeds(embed).setEphemeral(true).queue(); + + // Send the verification request in the manual verification channel + assert marketplace != null; + event.getGuild().getTextChannelById(Settings.Modules.Verification.manualVerification).sendMessageEmbeds( + new SimpleEmbedBuilder("Verification") + .text("A manual verification request has been made by " + member.getAsMention() + "!") + .field("User", member.getNickname() + " (" + member.getEffectiveName() + " " + member.getId() + ")", true) + .field("Marketplace", marketplace.getName(), true) + .field("Profile Link", link, true) + .field("Verification Code", code, true) + .field("Images", images, false) + .build() + ).queue(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/client/APIClient.java b/src/main/java/me/TechsCode/TechDiscordBot/client/APIClient.java deleted file mode 100644 index 8715e95f..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/client/APIClient.java +++ /dev/null @@ -1,15 +0,0 @@ -package me.TechsCode.TechDiscordBot.client; - -public class APIClient extends Thread { - private final String token; - - public APIClient(String token) { - this.token = token; - - start(); - } - - public String getToken() { - return token; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/applications/ApplicationCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/applications/ApplicationCommand.java new file mode 100644 index 00000000..692486a4 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/applications/ApplicationCommand.java @@ -0,0 +1,79 @@ +package me.techscode.techdiscordbot.commands.applications; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlApplication; +import me.techscode.techdiscordbot.modules.ApplyModule; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +import static me.techscode.techdiscordbot.modules.ApplyModule.applicationCreate; + +public class ApplicationCommand extends SimpleSlashCommand { + + public ApplicationCommand() { + super("application"); + + mainGuildOnly(); + + subCommands( + new SubcommandData("create", "Create a ticket"), + new SubcommandData("close", "Close a ticket") + ); + } + + @Override + protected void onCommand(@NotNull SlashCommandInteractionEvent event) { + + String subCommand = event.getSubcommandName(); + + assert subCommand != null; + if(subCommand.equals("create")) { + // Create the ticket channel + CompletableFuture future = applicationCreate(getMember(), getGuild()); + future.thenAccept(channel -> { + // Send a message to the user + event.replyEmbeds(new SimpleEmbedBuilder("Application Created") + .text( + "A new application has been created.", + "Please follow the steps in " + channel.getAsMention() + ) + .success().build()).setEphemeral(true).queue(); + }); + + } else if(subCommand.equals("close")) { + long channelId = event.getChannel().getIdLong(); + List sqlApplications = Database.APPLICATIONSTable.get(channelId); + + if (sqlApplications.size() == 0) { + event.replyEmbeds(new SimpleEmbedBuilder("Ticket Not Found") + .text("This channel is not a application. Please use this command in a application channel.", + "If you think this is a mistake, please contact a staff member.") + .error().build()).setEphemeral(true).queue(); + return; + } + + for (SqlApplication sqlApplication : sqlApplications) { + if (sqlApplication.getChannelId() != channelId) continue; + if (sqlApplication.getMember().get(0).getDiscordId() == event.getMember().getIdLong() || SimpleRoles.hasRole(event.getMember(), Settings.Roles.staff)) { + // Close the ticket + ApplyModule.applicationClose(sqlApplication.getChannel(), event.getTimeCreated().toEpochSecond()); + event.reply("Application closed").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + } else { + event.replyEmbeds(new SimpleEmbedBuilder("Not a owner or Staff member") + .text("You are not the owner of this Application or a staff member. There for you can't close it.") + .error().build()).setEphemeral(true).queue(); + } + return; + } + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/AnswerCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/AnswerCommand.java new file mode 100644 index 00000000..226459c1 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/AnswerCommand.java @@ -0,0 +1,73 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; + +import java.util.Objects; + +/** + * TODO: Fix all the commands and finish this file! + */ +public class AnswerCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public AnswerCommand() { + super("answer"); + description("give pre made answers to question"); + + mainGuildOnly(); + + subCommands( + new SubcommandData("hex", "Hex & gradient explanation"), + new SubcommandData("placeholderapi", "PlaceholderAPI explanation"), + new SubcommandData("test", "Test something out but no idea what!") + + ); + } + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + + switch (Objects.requireNonNull(event.getSubcommandName())) { + case "hex": + event.replyEmbeds( + new SimpleEmbedBuilder("How To Use Hex & Gradient") + .text("In order to use **Hex** and **Gradients** in Ultra and Insane plugins," + + "you will have to use two different formats.\n" + + "\n" + + "__For Hex Colors__ >\n" + + "```\n" + + "{#RRGGBB}Some Text```\n" + + "__For Gradients Colors__ >\n" + + "```{#RRGGBB>}Some Text{#RRGGBB<}```\n" + + "To be able to create gradient colors in an easier way and having a preview of them you can use this [**website**](https://rgb.techscode.com/), you have to select as `Type` **TechsCode {#rrggbb>}** then write the text you want to use in `Message`, after modify the colors and finally copy the text where it will be written `Output`.") + .success().build() + ).queue(); + break; + case "placeholderapi": + event.replyEmbeds( + new SimpleEmbedBuilder("How To Use Placeholders") + .text("In order to use **Placedholers** in Ultra and Insane plugins," + + "you will need to install [PlaceholderAPI](https://www.spigotmc.org/resources/placeholderapi.6245/).\n" + + "\n" + + "A list of all possible placeholders can be found [**HERE**](https://github.com/PlaceholderAPI/PlaceholderAPI/wiki/Placeholders)\n" + + "For a list of all our plugin placeholders, you will need to check our plugin wiki pages for each plugin you want to use placeholders from.") + .success().build() + ).queue(); + case "test": + event.reply(com.eaio.util.text.HumanTime.approximately("29 m 30m 100 ms")).queue(); + break; + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/GoogleCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/GoogleCommand.java new file mode 100644 index 00000000..faecdee3 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/GoogleCommand.java @@ -0,0 +1,88 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import org.jetbrains.annotations.NotNull; + +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + +public class GoogleCommand extends SimpleSlashCommand { + + public GoogleCommand() { + // Set the command + super("google"); + // Set the description of the command + description("Google something on the web"); + // Set the options for the command + options(new OptionData(OptionType.STRING, "search", "Your search phrase", true), + new OptionData(OptionType.USER, "member", "The member for who the search is", false)); + // Set to only the main guild + mainGuildOnly(); + } + + @Override + protected void onCommand(@NotNull final SlashCommandInteractionEvent event) { + + String search = Objects.requireNonNull(event.getOption("search")).getAsString(); + String queryUrl = null; + + try { + search = search.trim(); + search = URLEncoder + .encode(search, StandardCharsets.UTF_8); + queryUrl = "https://www.google.com/search?q=" + search; + + } catch (final Exception exception) { + Common.throwError(exception, "Something went wrong while searching for " + search); + } + + if (queryUrl == null) { + event.replyEmbeds(new SimpleEmbedBuilder("ERROR") + .text("Something went wrong while searching for " + search) + .error() + .build() + ).setEphemeral(true).queue(); + } + + OptionMapping targetOption = event.getOption("member"); + + if (targetOption == null) { + event.replyEmbeds( + new SimpleEmbedBuilder("Google") + .text( + "Hi there,", + "It seems that you don't know how to use google.", + "No problem at all, here is an example on how to google.", + "", + "Here is a google search for your question: " + queryUrl, + "", + "We hope this helps!" + ) + .build() + ).setEphemeral(true).queue(); + } else { + event.reply("Success!").setEphemeral(true).queue(message -> {message.deleteOriginal().queue();}); + event.getChannel().sendMessage(targetOption.getAsUser().getAsMention()).addEmbeds( + new SimpleEmbedBuilder("Google") + .text( + "Hi there,", + "It seems that you don't know how to use google.", + "No problem at all, here is an example on how to google.", + "", + "Here is a google search for your question: " + queryUrl, + "", + "We hope this helps!" + ) + .build() + ).queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/LinkCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/LinkCommand.java new file mode 100644 index 00000000..45bf1603 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/LinkCommand.java @@ -0,0 +1,90 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.model.enums.Plugin; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; + +import java.awt.*; +import java.util.Objects; + +public class LinkCommand extends SimpleSlashCommand { + + public LinkCommand() { + super("link"); + description("Will return a link to one of our websites"); + + subCommands(new SubcommandData("addon", "Returns the addon website"), + new SubcommandData("guides", "Returns the UC Guide website"), + new SubcommandData("insaneeditor", "Return the InsaneEditor website"), + new SubcommandData("polymart", "Returns the Polymart website"), + new SubcommandData("songoda", "Returns the Songoda website"), + new SubcommandData("spigot", "Returns the Spigot website"), + new SubcommandData("translations", "Returns the translations website") + ); + } + + @Override + protected void onCommand(SlashCommandInteractionEvent event) { + String subcommandData = event.getSubcommandName(); + + switch (Objects.requireNonNull(subcommandData)) { + case "addon" -> event.replyEmbeds(new SimpleEmbedBuilder("Addon Website") + .text("All our addon's are stored and manged thru our addons website.", + "https://ultraadditions.com/", + "", + "Welcome to the page where you can find, download, and upload addons to TechsCode's Plugins. Enhancing the capabilities of UltraCustomizer and UltraRegions.") + .color(new Color(192, 38, 211)) + .build()).queue(); + case "guides" -> event.replyEmbeds(new SimpleEmbedBuilder("Guides Website") + .text("Guides give more and a detailed example of how to setup or create a system for Ultra Customizer.", + "https://guides.techscode.com", + "", + "The guides website provides a simple website on how to use Ultra Customizer en on how to create a system. (This page might be integrated in to the main website in the future)") + .color(new Color(174, 84, 206)) + .image("https://i.imgur.com/KBw2szW.png") + .build()).queue(); + case "insaneeditor" -> event.replyEmbeds(new SimpleEmbedBuilder("Insane Editor") + .text("Use a web interface to edit in game settings and values of some of our plugins", + "**Under maintenance**", + "", + "This website allows you to edit permissions and settings for our plugins. Currently it is offline and being updated to a newer and faster system.") + .color(new Color(113, 225, 207)) + .image("https://i.imgur.com/4C08sQD.jpg") + .build()).queue(); + case "polymart" -> event.replyEmbeds(new SimpleEmbedBuilder("Polymart") + .text("Polymart is a marketplace where we sell our resources", + "https://polymart.org/user/techscode.5485", + "", + "Buy our resources from our marketplace and verify your purchase here: <#907349490556616745>") + .color(new Color(3, 160, 146)) + .image("https://i.imgur.com/1PXzrRg.png") + .build()).queue(); + case "songoda" -> event.replyEmbeds(new SimpleEmbedBuilder("Songoda") + .text("Songoda is a marketplace where we sell our resources", + "https://songoda.com/profile/techscode", + "", + "Buy our resources from our marketplace and verify your purchase here: <#907349490556616745>") + .color(new Color(252, 73, 74)) + .image("https://i.imgur.com/oKeIpv4.png") + .build()).queue(); + case "spigot" -> event.replyEmbeds(new SimpleEmbedBuilder("SpigotMC") + .text("SpigotMC is a marketplace where we sell our resources", + "https://www.spigotmc.org/members/techscode.29620/", + "", + "Buy our resources from our marketplace and verify your purchase here: <#907349490556616745>") + .color(new Color(238, 135, 19)) + .image("https://i.imgur.com/wlbnhwI.png") + .build()).queue(); + case "translations" -> event.replyEmbeds(new SimpleEmbedBuilder("Translations repository") + .text("All our translations can be found on our translation repository.", + "https://github.com/TechsCode-Team/PluginTranslations", + "", + "GitHub - TechsCode-Team/PluginTranslations: A repository holding the translations for our plugins.") + .color(new Color(67, 178, 255)) + .image("https://imgur.com/M2bHbUx.png") + .build()).queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/PluginCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/PluginCommand.java new file mode 100644 index 00000000..ea48acb5 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/PluginCommand.java @@ -0,0 +1,59 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.util.Objects; + +/** + * TODO: Fix all the commands and finish this file! + */ +public class PluginCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public PluginCommand() { + super("plugin"); + description("Get info/links about a plugin"); + + mainGuildOnly(); + + options(new OptionData(OptionType.STRING, "plugin", "Select a plugin", true) + .addChoice("Vault", "Vault") + .addChoice("PlaceholderAPI", "PlaceholderAPI") + .addChoice("ProtocolLib", "ProtocolLib") + .addChoice("TAB", "TAB") + .addChoice("NametagEdit", "NametagEdit")); + } + + // TODO: Make better embeds + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + final String topic = Objects.requireNonNull(event.getOption("plugin")).getAsString(); + + if (topic.equalsIgnoreCase("Vault")) { + event.reply("https://www.spigotmc.org/resources/vault.34315/").queue(); + } + if (topic.equalsIgnoreCase("PlaceholderAPI")) { + event.reply("https://www.spigotmc.org/resources/placeholderapi.6245/").queue(); + } + if (topic.equalsIgnoreCase("ProtocolLib")) { + event.reply("https://www.spigotmc.org/resources/protocollib.1997/").queue(); + } + if (topic.equalsIgnoreCase("TAB")) { + event.reply("https://github.com/NEZNAMY/TAB").queue(); + } + if (topic.equalsIgnoreCase("NametagEdit")) { + event.reply("https://github.com/NEZNAMY/TAB").queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/PreorderCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/PreorderCommand.java new file mode 100644 index 00000000..c6145e39 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/PreorderCommand.java @@ -0,0 +1,107 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.TranscriptDatabase; +import me.techscode.techdiscordbot.database.entities.SqlPreorder; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.awt.*; +import java.util.List; +import java.util.Objects; + +public class PreorderCommand extends SimpleSlashCommand { + + public PreorderCommand() { + super("preorder"); + description("Check if you have pre-ordered Insane Vaults."); + + mainGuildOnly(); + + options( + new OptionData(OptionType.STRING, "type", "What do you need?", true).addChoice("Check", "check").addChoice("Link", "link"), + new OptionData(OptionType.USER, "user", "The user to check the pre-order of.", false) + ); + } + + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { +/* + final String type = event.getOption("type").getAsString(); + + if (type.equals("check")) { + final User user = Objects.requireNonNull(event.getOption("user")).getAsUser(); + + if (!SimpleRoles.hasRole(getMember(), Settings.Roles.staff)) { + final List sqLPreorder = TranscriptDatabase.PREORDERS.get(getMember().getIdLong()); + + for (final SqlPreorder sqlPreorder : sqLPreorder) { + if (sqlPreorder.getDiscordId() == getMember().getIdLong() && !sqlPreorder.getTransactionId().equalsIgnoreCase("none")) { + event.replyEmbeds(new SimpleEmbedBuilder("Insane Vaults Preorder") + .text( + "**" + user.getAsMention() + " You have preorderd Insane Vaults!**", + "", + "You can access <#1058612057576054864> for your support questions.", + "To download the latest build of Insane Vaults go to the preorder page **[HERE](https://preorder.insanevaults.com/)**" + ) + .color(Color.getColor("#e74c3c")) + .thumbnail("https://cloud.techscode.com/s/J6SaqeQRrErQwft/preview") + .build() + ).setEphemeral(true).queue(); + } else { + event.replyEmbeds(new SimpleEmbedBuilder("Insane Vaults Preorder") + .text( + "**" + user.getAsMention() + " You haven't yet preorderd Insane Vaults!**", + "", + "You can preorder Insane Vaults **[HERE](https://preorder.insanevaults.com/)**" + ) + .color(Color.getColor("#e74c3c")) + .thumbnail("https://cloud.techscode.com/s/J6SaqeQRrErQwft/preview") + .build() + ).setEphemeral(true).queue(); + } + } + } else { + final List sqLPreorder = TranscriptDatabase.PREORDERS.get(user.getIdLong()); + + for (final SqlPreorder sqlPreorder : sqLPreorder) { + if (sqlPreorder.getDiscordId() == user.getIdLong() && !sqlPreorder.getTransactionId().equalsIgnoreCase("none")) { + event.replyEmbeds(new SimpleEmbedBuilder("Insane Vaults Preorder") + .text( + TechDiscordBot.getJDA().getUserById(sqlPreorder.getDiscordId()).getAsMention() + " has pre-ordered Insane Vaults!", + "", + "Transaction ID; " + sqlPreorder.getTransactionId() + ) + .color(Color.getColor("#e74c3c")) + .thumbnail("https://cloud.techscode.com/s/J6SaqeQRrErQwft/preview") + .build() + ).setEphemeral(true).queue(); + } else { + event.replyEmbeds(new SimpleEmbedBuilder("Insane Vaults Preorder") + .text( + TechDiscordBot.getJDA().getUserById(sqlPreorder.getDiscordId()).getAsMention() + " has not pre-ordered Insane Vaults!", + "", + "Transaction ID; " + sqlPreorder.getTransactionId() + ) + .color(Color.getColor("#e74c3c")) + .thumbnail("https://cloud.techscode.com/s/J6SaqeQRrErQwft/preview") + .build() + ).setEphemeral(true).queue(); + } + } + } + } + if (type.equals("link")) { + event.replyEmbeds(new SimpleEmbedBuilder("Preorder link") + .text("Pre-order here: https://preorder.insanevaults.com/") + .success().build() + ).setEphemeral(true).queue(); + }*/ + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/RemindCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/RemindCommand.java new file mode 100644 index 00000000..8a389088 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/RemindCommand.java @@ -0,0 +1,66 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.model.reminders.Reminder; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.text.SimpleDateFormat; +import java.util.Objects; + +/** + * TODO: Fix all the commands and finish this file! + */ +public class RemindCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public RemindCommand() { + super("remindme"); + description("Get reminded about something."); + + mainGuildOnly(); + + options( + new OptionData(OptionType.STRING, "time", "How long FROM NOW to be reminded.", true), + new OptionData(OptionType.STRING, "reminder", "What to be reminded about.", true), + new OptionData(OptionType.BOOLEAN, "private", "Whether to send the reminder in a dm or not.", false) + ); + } + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + final String time = event.getOption("time").getAsString(); + final String message = event.getOption("reminder").getAsString(); + final Boolean isPrivate = event.getOption("private") != null && event.getOption("private").getAsBoolean(); + + final Reminder reminder = TechDiscordBot.getRemindersManager().createReminder(event.getUser(), time, message, event.getChannel().asTextChannel(), isPrivate); + + if (reminder == null) { + event.replyEmbeds( + new SimpleEmbedBuilder("Reminder - Error") + .text("An error has occurred. Did you specify a time and a reason?\n\n**Here are some examples!**:\n`/remind 1 day Fix x thing.`\n`/remind 30 hours I need help.`\n`/remind 30 hours I need help. dm` (makes it a dm)") + .error() + .build() + ).setEphemeral(true).queue(); + } else { + event.replyEmbeds( + new SimpleEmbedBuilder("Reminder Set!") + .text("I will remind you for **" + reminder.getReminder() + "**!") + .success() + .build() + ).setEphemeral(true).queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/SubVerifyCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/SubVerifyCommand.java new file mode 100644 index 00000000..782c77b5 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/SubVerifyCommand.java @@ -0,0 +1,21 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +public class SubVerifyCommand extends SimpleSlashCommand { + + public SubVerifyCommand() { + super("subverify"); + description("Verify another person under your account."); + + options(new OptionData(OptionType.USER, "user", "The user to add to your account.", true)); + } + + @Override + protected void onCommand(SlashCommandInteractionEvent event) { + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/common/WikiCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/WikiCommand.java new file mode 100644 index 00000000..6e24a6c3 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/common/WikiCommand.java @@ -0,0 +1,100 @@ +package me.techscode.techdiscordbot.commands.common; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.model.enums.Plugin; +import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +import java.awt.*; + +public class WikiCommand extends SimpleSlashCommand { + + public WikiCommand() { + super("wiki"); + description("Get a wiki link for a plugin"); + } + + @Override + protected void onCommand(SlashCommandInteractionEvent event) { + + Channel channel = event.getChannel(); + + SimpleEmbedBuilder embedBuilder = new SimpleEmbedBuilder("📖 | Wiki"); + + + switch (channel.getId()) { + // Permissions + case "330053303050436608" -> event.replyEmbeds(embedBuilder.text("Here is the Ultra Permissions wiki", + Plugin.ULTRA_PERMISSIONS.getEmojiRaw() + " https://ultrapermissions.com/wiki") + .color(Plugin.ULTRA_PERMISSIONS.getRole().getColor()) + .build()).queue(); + + // Scoreboards + case "858052621574078474" -> event.replyEmbeds(embedBuilder.text("Here is the Ultra Scoreboards wiki", + Plugin.ULTRA_SCOREBOARDS.getEmojiRaw() + " https://ultrascoreboards.com/wiki") + .color(Plugin.ULTRA_SCOREBOARDS.getRole().getColor()) + .build()).queue(); + + // Punishments + case "531251918291599401" -> event.replyEmbeds(embedBuilder.text("Here is the Ultra Punishments wiki", + Plugin.ULTRA_PUNISHMENTS.getEmojiRaw() + " https://ultrapunishments.com/wiki") + .color(Plugin.ULTRA_PUNISHMENTS.getRole().getColor()) + .build()).queue(); + + // Customizer + case "380133603683860480" -> event.replyEmbeds(embedBuilder.text("Here is the Ultra Customizer wiki", + Plugin.ULTRA_CUSTOMIZER.getEmojiRaw() + " https://ultracustomizer.com/wiki") + .color(Plugin.ULTRA_CUSTOMIZER.getRole().getColor()) + .build()).queue(); + + // Economy + case "737773631198986240" -> event.replyEmbeds(embedBuilder.text("Here is the Ultra Economy wiki", + Plugin.ULTRA_ECONOMY.getEmojiRaw() + " https://ultraeconomy.com/wiki") + .color(Plugin.ULTRA_ECONOMY.getRole().getColor()) + .build()).queue(); + + // Regions + case "465975795433734155" -> event.replyEmbeds(embedBuilder.text("Here is the Ultra Regions wiki", + Plugin.ULTRA_REGIONS.getEmojiRaw() + " https://ultraregions.com/wiki") + .color(Plugin.ULTRA_REGIONS.getRole().getColor()) + .build()).queue(); + + // MOTD + case "931264562995540038" -> event.replyEmbeds(embedBuilder.text("Here is the Ultra MOTD wiki", + Plugin.ULTRA_MOTD.getEmojiRaw() + " https://ultramotd.com/wiki") + .color(Plugin.ULTRA_MOTD.getRole().getColor()) + .build()).queue(); + + // Shops + case "576813543698202624" -> event.replyEmbeds(embedBuilder.text("Here is the Insane Shops wiki", + Plugin.INSANE_SHOPS.getEmojiRaw() + " https://insaneshops.com/wiki") + .color(Plugin.INSANE_SHOPS.getRole().getColor()) + .build()).queue(); + + // Vaults + case "1058612057576054864" -> event.replyEmbeds(embedBuilder.text("Here is the Insane Vaults wiki", + Plugin.INSANE_VAULTS.getEmojiRaw() + " https://insanevaults.com/wiki") + .color(Plugin.INSANE_VAULTS.getRole().getColor()) + .build()).queue(); + default -> event.replyEmbeds(new SimpleEmbedBuilder("📚 | Wiki") + .text("Showing all wiki's") + .field( + "Wiki's", + Plugin.ULTRA_PERMISSIONS.getEmojiRaw() + " https://ultrapermissions.com/wiki\n" + + Plugin.ULTRA_CUSTOMIZER.getEmojiRaw() + " https://ultracustomizer.com/wiki\n" + + Plugin.ULTRA_ECONOMY.getEmojiRaw() + " https://ultraeconomy.com/wiki\n" + + Plugin.ULTRA_REGIONS.getEmojiRaw() + " https://ultraregions.com/wiki\n" + + Plugin.ULTRA_PUNISHMENTS.getEmojiRaw() + " https://ultrapunishments.com/wiki\n" + + Plugin.ULTRA_SCOREBOARDS.getEmojiRaw() + " https://ultrascoreboards.com/wiki\n" + + Plugin.ULTRA_MOTD.getEmojiRaw() + " https://ultramotd.com/wiki\n" + + Plugin.INSANE_VAULTS.getEmojiRaw() + " https://insanevaults.com/wiki\n" + + Plugin.INSANE_SHOPS.getEmojiRaw() + " https://insaneshops.com/wiki\n" + + Plugin.INSANE_ANNOUNCER.getEmojiRaw() + " https://insaneannouncer.com/wiki\n", + false + ) + .build() + ).queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/console/SayConsoleCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/console/SayConsoleCommand.java new file mode 100644 index 00000000..6fb0cf6f --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/console/SayConsoleCommand.java @@ -0,0 +1,39 @@ +package me.techscode.techdiscordbot.commands.console; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.handlers.console.SimpleConsoleCommand; +import me.techscode.techdiscordbot.TechDiscordBot; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; + +import java.util.List; + +public class SayConsoleCommand extends SimpleConsoleCommand { + public SayConsoleCommand() { + super("say"); + description("Says something from the console to an specific channel"); + usage("say "); + } + + @Override + public void onConsoleCommand(List args) { + if (args.isEmpty() || args.size() < 2) { + sendUsage(); + return; + } + + String channelId = args.get(0); + String message = String.join(" ", args.subList(1, args.size())); + + TextChannel textChannel = TechDiscordBot.getMainGuild().getTextChannelById(channelId); + + if (textChannel == null) { + Common.error("Channel not found!"); + sendUsage(); + return; + } + + textChannel.sendMessage(message).queue(); + Common.log("Message sent to " + textChannel.getName() + ": " + message); + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/debug/DatabaseCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/debug/DatabaseCommand.java new file mode 100644 index 00000000..a05bfb1c --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/debug/DatabaseCommand.java @@ -0,0 +1,109 @@ +package me.techscode.techdiscordbot.commands.debug; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlMember; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData; + +import java.util.List; + +public class DatabaseCommand extends SimpleSlashCommand { + + + public DatabaseCommand() { + super("database"); + description("Test the database connection, outputs and more."); + + mainGuildOnly(); + + subcommandGroup(new SubcommandGroupData("debug", "Debug some things from the database").addSubcommands( + new SubcommandData("member", "Check the database connection").addOption(OptionType.MENTIONABLE, "member", "The user to check", true), + new SubcommandData("verification", "Check the verification of a user").addOption(OptionType.MENTIONABLE, "member", "The user to check", true) + ) + ); + + subCommands( + new SubcommandData("import", "Import all members from the guild to the database") + ); + + } + + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + if (event.getSubcommandGroup().equals("debug")) { + switch (event.getSubcommandName()) { + case "member": + Member member = event.getOption("member").getAsMember(); + final List sqlMemberList = Database.MEMBERSTable.getFromDiscordId(member.getIdLong()); + for (final SqlMember sqlMember : sqlMemberList) { + event.replyEmbeds(new SimpleEmbedBuilder("Database check") + .text("Success fully retrieved the member " + sqlMember.getDiscordMember().getAsMention() + " from the database.") + .field("ID: ", String.valueOf(sqlMember.getDiscordId()), true) + .field("Table ID:", String.valueOf(sqlMember.getId()), true) + .success().build() + ).setEphemeral(true).queue(); + } + return; + case "verification": + + } + } + switch (event.getSubcommandName()) { + case "import": + event.replyEmbeds(new SimpleEmbedBuilder("Database import") + .text("Importing all members from the guild to the database.") + .thumbnail("https://i.imgur.com/jcuD6gb.gif") + .build() + ).setEphemeral(true).queue(); + + + final Thread thread = new Thread(() -> { + event.getGuild().loadMembers().onSuccess(members -> { + int numInteractions = members.size() +1; + int i = 0; + for (final Member member : members) { + + if (Database.MEMBERSTable.getFromDiscordId(member.getIdLong()).isEmpty()) { + event.getHook().editOriginalEmbeds(new SimpleEmbedBuilder("Database import") + .text("Importing all members from the guild to the database.") + .thumbnail("https://i.imgur.com/jcuD6gb.gif") + .build() + ).queue(); + + Database.MEMBERSTable.add(new SqlMember(member.getIdLong())); + Common.log("Imported " + member.getUser().getAsTag() + " to the database."); + } else { + Common.log("Skipped " + member.getUser().getAsTag() + " because it's already in the database."); + } + + if (i % 10 == 0) { + event.getHook().editOriginalEmbeds(new SimpleEmbedBuilder("Database import") + .text("Importing all members from the guild to the database.", "Progress: " + i + "/" + members.size()) + .thumbnail("https://i.imgur.com/jcuD6gb.gif") + .build() + ).queue(); + } + + i++; + } + Common.log("Finished importing all members from the guild to the database."); + + if (i == members.size()) { + event.getHook().editOriginalEmbeds(new SimpleEmbedBuilder("Database import") + .text("All members have been imported.") + .success().build() + ).queue(); + } + }); + }); + thread.setName("DatabaseCommand-" + getUser().getId()); + thread.start(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/BotCommands.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/BotCommands.java new file mode 100644 index 00000000..ff0f74a0 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/BotCommands.java @@ -0,0 +1,142 @@ +package me.techscode.techdiscordbot.commands.staff; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.actions.buttons.BotActionButtons; +import me.techscode.techdiscordbot.modules.ApplyModule; +import me.techscode.techdiscordbot.modules.TicketModule; +import me.techscode.techdiscordbot.modules.VerificationModule; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; + +import java.util.Objects; +import java.util.concurrent.TimeUnit; + +public class BotCommands extends SimpleSlashCommand { + + public BotCommands() { + super("manage"); + description("manage some things in the bot"); + + subCommands( + new SubcommandData("restart", "restart the bot"), + /*new SubcommandData("shutdown", "shutdown the bot"),*/ + new SubcommandData("embeds", "manage embeds") + .addOptions( + new OptionData(OptionType.STRING, "type", "the type of embed", true) + .addChoice("overview", "overview") + .addChoice("ticket", "ticket") + .addChoice("application", "application") + .addChoice("verification", "verification"), + new OptionData(OptionType.STRING, "action", "the action to perform", true) + .addChoice("send", "send") + .addChoice("resend", "resend") + .addChoice("remove", "remove") + ) + ); + + + mainGuildOnly(); + } + + @Override + protected void onCommand(SlashCommandInteractionEvent event) { + String subCommand = event.getSubcommandName(); + + switch (Objects.requireNonNull(subCommand)) { + case "restart" -> { + event.replyEmbeds(new SimpleEmbedBuilder("Restart") + .text("To restart the bot you need to to confirm you want to restart the bot. To do this, press the Confirm button below.") + .error().build()).addActionRow(new BotActionButtons.shutdown().build()).setEphemeral(true).queue(); + TechDiscordBot.getInstance().stop(); + } + case "shutdown" -> event.replyEmbeds(new SimpleEmbedBuilder("Shutdown") + .text("To shutdown the bot you need to to confirm you want to stop the bot. To do this, press the Confirm button below.") + .error().build()).addActionRow(new BotActionButtons.shutdown().build()).setEphemeral(true).queue(); + case "embeds" -> { + String type = Objects.requireNonNull(event.getOption("type")).getAsString(); + String action = Objects.requireNonNull(event.getOption("action")).getAsString(); + + + SimpleEmbedBuilder embed = new SimpleEmbedBuilder("Embeds").success(); + TextChannel channel; + switch (type) { + case "overview": + break; + case "ticket": + channel = event.getJDA().getTextChannelById(Settings.Modules.Ticket.channel); + assert channel != null; + switch (action) { + case "send" -> { + TicketModule.embed(); + embed.text("The embed has been sent.", + channel.getAsMention()); + } + case "resend" -> { + channel.getIterableHistory().takeAsync(10).thenAccept(channel::purgeMessages); + TicketModule.embed(); + embed.text("The embed has been resent.", + channel.getAsMention()); + } + case "remove" -> { + channel.getIterableHistory().takeAsync(10).thenAccept(channel::purgeMessages); + embed.text("The embed has been removed.", + channel.getAsMention()); + } + } + break; + case "application": + channel = event.getJDA().getTextChannelById(Settings.Modules.Apply.channel); + assert channel != null; + switch (action) { + case "send" -> { + ApplyModule.embed(); + embed.text("The embed has been sent.", + channel.getAsMention()); + } + case "resend" -> { + channel.getIterableHistory().takeAsync(10).thenAccept(channel::purgeMessages); + ApplyModule.embed(); + embed.text("The embed has been resent.", + channel.getAsMention()); + } + case "remove" -> { + channel.getIterableHistory().takeAsync(10).thenAccept(channel::purgeMessages); + embed.text("The embed has been removed.", + channel.getAsMention()); + } + } + break; + case "verification": + channel = event.getJDA().getTextChannelById(Settings.Modules.Verification.channel); + assert channel != null; + switch (action) { + case "send" -> { + VerificationModule.embed(); + embed.text("The embed has been sent.", + channel.getAsMention()); + } + case "resend" -> { + channel.getIterableHistory().takeAsync(10).thenAccept(channel::purgeMessages); + VerificationModule.embed(); + embed.text("The embed has been resent.", + channel.getAsMention()); + } + case "remove" -> { + channel.getIterableHistory().takeAsync(10).thenAccept(channel::purgeMessages); + embed.text("The embed has been removed.", + channel.getAsMention()); + } + } + break; + } + event.replyEmbeds(embed.build()).setEphemeral(true).queue(); + } + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/PruneCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/PruneCommand.java new file mode 100644 index 00000000..c841e0fb --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/PruneCommand.java @@ -0,0 +1,123 @@ +package me.techscode.techdiscordbot.commands.staff; + +import com.greazi.discordbotfoundation.handlers.buttons.SimpleButton; +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.entities.channel.middleman.MessageChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.events.interaction.component.ButtonInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.components.buttons.ButtonStyle; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class PruneCommand extends SimpleSlashCommand { + + public PruneCommand() { + super("clear"); + description("Clear a certain amount of messages"); + + options( + new OptionData(OptionType.INTEGER, "amount", "The number of messages to clear", true), + new OptionData(OptionType.CHANNEL, "channel", "The channel to delete messages from", false) + ); + } + + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + // Get the command sender + final User executor = event.getUser(); + + // Get the guild from the event + final Guild guild = event.getGuild(); + assert guild != null; + + final int amount = event.getOption("amount").getAsInt(); + final TextChannel channel = event.getOption("channel").getAsChannel().asTextChannel(); + + + final List messages = channel.getHistory().retrievePast(amount).complete(); + + event.reply("**This will delete " + amount + " messages.**\nAre you sure?") + .addActionRow( + new ConfirmButton(executor.getId(), amount).build(), + new CancelButton(executor.getId()).build() + ).queue(); + } + + /** + * The prune confirm button + */ + public static class ConfirmButton extends SimpleButton { + + /** + * Set the button details + */ + public ConfirmButton(final String userId, final int amount) { + super(userId + ":prune:" + amount); + label("Confirm"); + buttonStyle(ButtonStyle.SUCCESS); + disabled(false); + } + + /** + * The execution once the button has been pressed + * + * @param event ButtonInteractionEvent + */ + @Override + protected void onButtonInteract(@NotNull final ButtonInteractionEvent event) { + final String[] id = event.getComponentId().split(":"); + + final String authorId = id[0]; + final int amount = Integer.parseInt(id[2]); + + if (!authorId.equals(event.getUser().getId())) + return; + + final MessageChannel channel = event.getChannel(); + event.deferEdit().queue(); + + event.getChannel().getIterableHistory() + .skipTo(event.getMessageIdLong()) + .takeAsync(amount) + .thenAccept(channel::purgeMessages); + } + } + + /** + * The prune cancel button + */ + public static class CancelButton extends SimpleButton { + + /** + * Set the button details + */ + public CancelButton(final String userId) { + super(userId + ":cancelprune"); + label("Cancel"); + buttonStyle(ButtonStyle.DANGER); + disabled(false); + } + + /** + * The execution once the button has been pressed + * + * @param event ButtonInteractionEvent + */ + @Override + protected void onButtonInteract(@NotNull final ButtonInteractionEvent event) { + final String[] id = event.getComponentId().split(":"); + + final String authorId = id[0]; + + if (!authorId.equals(event.getUser().getId())) + return; + + event.getHook().deleteOriginal().queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/QuestionCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/QuestionCommand.java new file mode 100644 index 00000000..840b910a --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/QuestionCommand.java @@ -0,0 +1,192 @@ +package me.techscode.techdiscordbot.commands.staff; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlMember; +import me.techscode.techdiscordbot.database.entities.SqlTicket; +import me.techscode.techdiscordbot.modules.TicketModule; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandGroupData; + +import java.util.List; +import java.util.Objects; + +public class QuestionCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public QuestionCommand() { + super("q"); + description("give pre made answers and questions"); + + mainGuildOnly(); + + subcommandGroup(new SubcommandGroupData("ticket", "ticket answers and questions") + .addSubcommands(new SubcommandData("unverified", "Unverified premium plugin support ticket").addOption(OptionType.USER, "user", "The user that needs to be pinged", true)) + .addSubcommands(new SubcommandData("close", "Ask the owner if the ticket can be closed")), + new SubcommandGroupData("spark", "spark answers and questions") + .addSubcommands(new SubcommandData("info", "Give information about spark").addOption(OptionType.USER, "user", "The user that needs this info", false)) + .addSubcommands(new SubcommandData("report", "Ask for a spark report") + .addOptions( + new OptionData(OptionType.STRING, "type", "The type of report you want to ask for", true) + .addChoice("profiler", "profiler") + .addChoice("health", "health") + .addChoice("tickmonitor", "tickmonitor") + .addChoice("garbagecollection", "garbagecollection") + .addChoice("heapsummary", "heapsummary") + .addChoice("heapdump", "heapdump") + ) + .addOption(OptionType.USER, "user", "The user you want to ask for a spark report", false)) + ); + } + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + + + if (event.getSubcommandGroup().equals("ticket")) { + switch (Objects.requireNonNull(event.getSubcommandName())) { + case "unverified" -> { + event.reply("success").queue(message -> message.deleteOriginal().queue()); + event.getMessageChannel().sendMessage(event.getOption("user").getAsUser().getAsMention()).addEmbeds( + new SimpleEmbedBuilder("Premium plugin support") + .text( + "Hi there,", + "", + "It seems that you are trying to make a support ticket for a premium plugin, but you are not verified.", + "In order to get verified, you need to verify your purchase in <#907349490556616745>", + "Once you are verified, you will be able to make support tickets for premium plugins.", + "", + "If you have already send a verification request, please wait for a staff member to verify your purchase.", + "", + "If you have a pre sale question go to <#916558825367158794>", + "", + "This ticket will be closed in 1 hour." + ).build() + ).queue(); + TicketModule.ticketClose(event.getOption("user").getAsMember(), Database.TICKETS.get(event.getChannel().getIdLong()).get(0), event.getTimeCreated().toEpochSecond(), "For pre sale question go to <#916558825367158794>, for verifying purchases go to <#907349490556616745>", 3600000); + } + case "close" -> { + event.reply("success").queue(message -> message.deleteOriginal().queue()); + long channelId = event.getChannel().getIdLong(); + List sqlTickets = Database.TICKETS.get(channelId); + if (sqlTickets.size() == 0) { + event.replyEmbeds(new SimpleEmbedBuilder("Further assistance") + .text( + "Hi there,", + "", + "We would like to know if we can close this ticket.", + "If you need further assistance, please reply to this message.", + "", + "This ticket will be closed in 24 hours if no reply is given." + ) + .error().build()).setEphemeral(true).queue(); + return; + } + SqlMember sqlMember = sqlTickets.get(0).getMember(); + event.getMessageChannel().sendMessage(sqlMember.getDiscordMember().getAsMention()).addEmbeds( + new SimpleEmbedBuilder("Further assistance") + .text( + "Hi there,", + "", + "We would like to know if we can close this ticket.", + "If you need further assistance, please reply to this message.", + "", + "This ticket will be closed in 24 hours if no reply is given." + ).build() + ).queue(); + return; + } + } + } + + if (event.getSubcommandGroup().equals("spark")) { + SimpleEmbedBuilder embed = new SimpleEmbedBuilder(); + + if (Objects.equals(event.getSubcommandName(), "info")) { + embed.setAuthor("⚡ Spark"); + embed.text("Spark is a plugin that allows you to see what is happening on your server.", + "", + "You can find more information about Spark on [their website](https://spark.lucko.me)."); + event.replyEmbeds(embed.build()).queue(); + return; + } + + if (Objects.equals(event.getSubcommandName(), "report")) { + switch (Objects.requireNonNull(event.getOption("type")).getAsString()) { + case "profiler" -> { + embed.setAuthor("⚡ Spark Profiler"); + embed.text("It seems that we would like to receive a Spark report from your server.", + "", + "[Spark](https://spark.lucko.me) is a plugin that allows you to see what is happening on your server.") + .field("Create a Spark Profile", "To create a report you need to run `/spark profiler start`\nOnce you are ready to see the results use `/spark profiler stop` to view the end result.", false) + .field("How long should the Profile last?", "The longer the profile runs the more accurate the results will be.\nWe recommend running the profile for at least 30 minutes.", false); + } + case "health" -> { + embed.setAuthor("⚡ Spark Health"); + embed.text("It seems that we would like a Spark Health report from your server.", + "", + "[Spark](https://spark.lucko.me) is a plugin that allows you to see what is happening on your server.") + .field("Create a Spark Health report", "To create a report you need to run `/spark health `.\nProvide this report and if needed the one down below.", false) + .field("Additional commands", "`/spark health --memory` is needed when there are memory issues.\n`/spark health --network` is needed when there are network issues.", false); + } + case "tickmonitor" -> { + embed.setAuthor("⚡ Spark Tick-monitor"); + embed.text("We would like to investigate what is happening on your server if you are experiencing lag.", + "The Spark Tickmonitor is a tool that shows the duration of a tick as well as what occurs during a tick.", + "", + "[Spark](https://spark.lucko.me) is a plugin that allows you to see what is happening on your server.") + .field("Enable Tick-monitor", "To enable the Tickmonitor you need to run `/spark tickmonitor`. This commands toggles the status of the ticketmonitor.", false) + .field("Additional commands", "`/spark tickmonitor --threshold ` only reporting ticks which exceed a percentage increase from the average tick duration.\n`/spark tickmonitor --threshold-tick ` only reporting ticks which exceed the given duration in milliseconds.\n`/spark tickmonitor --without-gc` disable reports about GC activity.", false); + } + case "garbagecollection" -> { + embed.setAuthor("⚡ Spark Garbage Collection"); + embed.text("It seems that we need to take a deeper look in your memory.", + "There for we are gonna take a look in your GC (Garbage Collection).", + "", + "[Spark](https://spark.lucko.me) is a plugin that allows you to see what is happening on your server.") + .field("Print GC", "To print your GC you need to run `/spark gc`", false) + .field("Monitor GC", "To activly view your GC you need to run `/spark gcmonitor`", false); + } + case "heapsummary" -> { + embed.setAuthor("⚡ Spark Heap summary"); + embed.text("It seems that we need a better look at what is stored in your memory.", + "", + "[Spark](https://spark.lucko.me) is a plugin that allows you to see what is happening on your server.") + .field("Get Heapsummary", "To get a Heapsummary your need to run `/spark heapsummary` this returns a view with all data stored in its memory", false); + } + case "heapdump" -> { + embed.setAuthor("⚡ Spark Heapdump"); + embed.text("Spark has an option to generates a new heapdump (.hprof snapshot) file and saves that heapdump to the disk.", + "**NOTE;** This require as much space as your available RAM!", + "", + "[Spark](https://spark.lucko.me) is a plugin that allows you to see what is happening on your server.") + .field("Create Heapdump", "To create a Heapdump run `/spark heapdump` this saves a file to your disk.", false) + .field("Additional commands", "`/spark heapdump --compress ` to specify that the heapdump should be compressed using the given type. The supported types are gzip, xz and lzma.", false); + } + } + } + + OptionMapping user = event.getOption("user"); + if (user == null) { + event.replyEmbeds(embed.build()).queue(); + } else { + event.reply("<@" + user.getAsUser().getId() + ">").addEmbeds(embed.build()).queue(); + } + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/RoleCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/RoleCommand.java new file mode 100644 index 00000000..0b97abac --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/RoleCommand.java @@ -0,0 +1,81 @@ +package me.techscode.techdiscordbot.commands.staff; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.handlers.selectmenu.string.SimpleStringSelectMenu; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.actions.menus.RolesMenu; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import net.dv8tion.jda.api.interactions.components.selections.StringSelectInteraction; + +/** + * TODO: Fix all the commands and finish this file! + */ +public class RoleCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public RoleCommand() { + super("role"); + description("add roles to a user"); + + mainGuildOnly(); + + subCommands( + new SubcommandData("add", "add roles to a user").addOption(OptionType.USER, "user", "The user to add roles", true), + new SubcommandData("remove", "remove roles from a user").addOption(OptionType.USER, "user", "The user to remove roles", true) + + ); + options(new OptionData(OptionType.USER, "user", "The user to add roles", true)); + } + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + final User target = event.getOption("user").getAsUser(); + + // Get the guild where the command was executed + final Guild guild = event.getGuild(); + assert guild != null; + + // Get the member from the guild + final Member guildMember = guild.getMember(target); + + if (guildMember == null) { + event.reply("The user is not in this guild.").setEphemeral(true).queue(); + return; + } + + switch (event.getSubcommandName()) { + case "add" -> event.replyEmbeds( + new SimpleEmbedBuilder("Add Roles") + .text("Select the roles you want to add to member " + guildMember.getAsMention() + ".") + .build() + ) + .addActionRow( + new RolesMenu.Add(guildMember).build() + ).setEphemeral(true).queue(); + case "remove" -> event.replyEmbeds( + new SimpleEmbedBuilder("Remove Roles") + .text("Select the roles you want to remove from member " + guildMember.getAsMention() + ".") + .build() + ) + .addActionRow( + new RolesMenu.Remove(guildMember).build() + ).setEphemeral(true).queue(); + } + + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UpdateCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UpdateCommand.java new file mode 100644 index 00000000..b6929f69 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UpdateCommand.java @@ -0,0 +1,56 @@ +package me.techscode.techdiscordbot.commands.staff; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.utils.Changelog; +import net.dv8tion.jda.api.entities.channel.Channel; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class UpdateCommand extends SimpleSlashCommand { + + public UpdateCommand() { + super("update"); + description("Send an update embed to an channel"); + + OptionData optionData = new OptionData(OptionType.STRING, "version", "The version of the update", true); + + for (Changelog changelog : Changelog.values()) { + optionData.addChoice(changelog.getVersion(), changelog.name()); + } + + options( + optionData, + new OptionData(OptionType.CHANNEL, "channel", "The channel to send the update to", false) + + ); + + mainGuildOnly(); + } + + @Override + protected void onCommand(@NotNull SlashCommandInteractionEvent event) { + String version = Objects.requireNonNull(event.getOption("version")).getAsString(); + OptionMapping channelOptionMapping = event.getOption("channel"); + + Changelog changelog = Changelog.valueOf(version); + + SimpleEmbedBuilder embed = new SimpleEmbedBuilder("Update " + changelog.getVersion()) + .field("Changes:", "- " + String.join("\n- ", changelog.getChanges()), false); + + if (channelOptionMapping == null) { + event.replyEmbeds(embed.build()).setEphemeral(true).queue(); + } else { + channelOptionMapping.getAsChannel().asTextChannel().sendMessageEmbeds(embed.build()).queue(); + } + + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UserInfoCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UserInfoCommand.java new file mode 100644 index 00000000..1bdd6091 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/UserInfoCommand.java @@ -0,0 +1,55 @@ +package me.techscode.techdiscordbot.commands.staff; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.time.format.DateTimeFormatter; +import java.util.Objects; +import java.util.stream.Collectors; + +/** + * The mute command to mute an player + */ +public class UserInfoCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public UserInfoCommand() { + super("info"); + description("Get information about a specific user."); + + mainGuildOnly(); + + options(new OptionData(OptionType.USER, "member", "The member that needs a timeout", true)); + } + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + final Member member = event.getOption("member") == null ? event.getMember() : Objects.requireNonNull(event.getOption("member")).getAsMember(); + assert member != null; + final User user = member.getUser(); + + event.replyEmbeds( + new SimpleEmbedBuilder(user.getName() + "#" + user.getDiscriminator()) + .field("ID", user.getId(), true) + .field("Status", member.getOnlineStatus().getKey().substring(0, 1).toUpperCase() + member.getOnlineStatus().getKey().substring(1), true) + .field("Times", "Created: " + user.getTimeCreated().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")) + ", Joined: " + member.getTimeJoined().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")), true) + .field("Flags", user.getFlags().clone().stream().map(User.UserFlag::getName).collect(Collectors.joining(", ")), true) + .field("Roles", member.getRoles().stream().map(Role::getAsMention).collect(Collectors.joining(", ")), true) + .thumbnail(user.getAvatarUrl()) + .build() + ).queue(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/BanCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/BanCommand.java new file mode 100644 index 00000000..3f13cee0 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/BanCommand.java @@ -0,0 +1,88 @@ +package me.techscode.techdiscordbot.commands.staff.punishment; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.model.Logs; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.time.temporal.ChronoUnit; +import java.util.concurrent.TimeUnit; + +public class BanCommand extends SimpleSlashCommand { + + /** + * Create the ban command with its specific settings + */ + public BanCommand() { + super("ban"); + description("Ban a person from the guild"); + + // Se the specific options that can be used for the command + options( + new OptionData(OptionType.USER, "user", "The user to ban", true), + new OptionData(OptionType.STRING, "reason", "The reason for the banning", true) + ); + } + + /** + * The main code of the ban command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + // Get the command sender + final User executor = event.getUser(); + + // Get the guild where the command was executed + final Guild guild = event.getGuild(); + assert guild != null; + + // Get the options from the command + final User target = event.getOption("user").getAsUser(); + final String reason = event.getOption("reason").getAsString(); + + // Get the member from the guild + final Member guildMember = guild.getMember(target); + + // Check if the target isn't null + if (guildMember == null) { + event.reply("The user is not in this guild.").setEphemeral(true).queue(); + return; + } + + // Check if the target is a staff member + if (SimpleRoles.hasRole(guildMember, "staff") || SimpleRoles.hasRole(guildMember, "Bot")) { + event.reply("You are not allowed to ban a staff member or a BOT").setEphemeral(true).queue(); + return; + } + + // Add a new ban to the guild's ban list + guild.ban(target, 1, TimeUnit.DAYS) + .reason(reason) + .queue(); + + SimpleEmbedBuilder embed = new SimpleEmbedBuilder("Ban | " + target.getName()) + .text("Banned a user from the GUILD;") + .field("Target;", target.getAsMention(), true) + .field("Staff Member;", executor.getAsMention(), true) + .field("Reason;", reason, false) + .error(); + + // An extra check to see if the guild is really the main guild + if (guild == TechDiscordBot.getMainGuild()) { + Logs.PunishLogs.log( + embed + ); + } + + event.replyEmbeds(embed.build()).setEphemeral(true).queue(); + } +} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/KickCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/KickCommand.java new file mode 100644 index 00000000..0fcb03ac --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/KickCommand.java @@ -0,0 +1,77 @@ +package me.techscode.techdiscordbot.commands.staff.punishment; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.model.Logs; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +public class KickCommand extends SimpleSlashCommand { + + /** + * Create the kick command with its specific settings + */ + public KickCommand() { + super("kick"); + description("Kick a user from the guild"); + + // Set the specific options that can be used for the command + options( + new OptionData(OptionType.USER, "user", "The user to kick", true), + new OptionData(OptionType.STRING, "reason", "The reason for the kicking", true) + ); + } + + /** + * The main code of the kick command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + // Get the command sender + final User executor = event.getUser(); + + // Get the guild from the event + final Guild guild = event.getGuild(); + assert guild != null; + + // Get the options from the command + final User target = event.getOption("user").getAsUser(); + final String reason = event.getOption("reason").getAsString(); + + // Get the member from the guild + final Member guildMember = guild.getMember(target); + + // Check if the target isn't null + if (guildMember == null) { + event.reply("The user is not in this guild.").setEphemeral(true).queue(); + return; + } + + // Check if the target is a staff member + if (guildMember.getRoles().contains(SimpleRoles.getRoleByName(getGuild(), "staff")) || guildMember.getRoles().contains(SimpleRoles.getRoleByName(getGuild(), "bot"))) { + event.reply("You are not allowed to kick a staff member or a BOT").setEphemeral(true).queue(); + return; + } + + // Kick the user from the guild + guild.kick(target, reason).queue(); + + if (guild == TechDiscordBot.getMainGuild()) { + Logs.PunishLogs.log( + new SimpleEmbedBuilder("Kick | " + target.getName()) + .text("Kicked a user from the GUILD;") + .field("Target;", target.getAsMention(), true) + .field("Staff member;", executor.getAsMention(), true) + .field("Reason;", reason, false) + ); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/TimeoutCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/TimeoutCommand.java new file mode 100644 index 00000000..98f59d45 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/TimeoutCommand.java @@ -0,0 +1,143 @@ +package me.techscode.techdiscordbot.commands.staff.punishment; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.model.Logs; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +import java.util.concurrent.TimeUnit; + +/** + * The mute command to mute an player + */ +public class TimeoutCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public TimeoutCommand() { + super("timeout"); + description("Timeout a user"); + + mainGuildOnly(); + + // Set the options for the command + options( + new OptionData(OptionType.USER, "user", "The user to timeout", true), + new OptionData(OptionType.STRING, "duration", "The duration", true), + new OptionData(OptionType.STRING, "timeunit", "The time unit (s, h, d, w, m) of the timeout", true) + .addChoice("seconds", "s") + .addChoice("minutes", "m") + .addChoice("hours", "h") + .addChoice("days", "d") + .addChoice("weeks", "w") + .addChoice("months", "M"), + new OptionData(OptionType.STRING, "reason", "The reason for the timeout", true) + ); + } + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + // Get the command sender + final User executor = event.getUser(); + + // Get the guild from the event + final Guild guild = event.getGuild(); + assert guild != null; + + final User target = event.getOption("user").getAsUser(); + final String duration = event.getOption("duration").getAsString(); + final String timeunit = event.getOption("timeunit").getAsString(); + final String reason = event.getOption("reason").getAsString(); + + // Get the member from the guild + final Member guildMember = guild.getMember(target); + + // Check if the target isn't null + if (guildMember == null) { + event.reply("The user is not in this guild.").setEphemeral(true).queue(); + return; + } + + // Check if the target is a staff member + if (guildMember.getRoles().contains(SimpleRoles.getRoleByName(getGuild(), "staff")) || guildMember.getRoles().contains(SimpleRoles.getRoleByName(getGuild(), "bot"))) { + event.reply("You are not allowed to timeout a staff member or a BOT").setEphemeral(true).queue(); + return; + } + + // TODO: Fix this part to make it simpler + + // Retrieve the time option of the command + long time = event.getOption("time").getAsLong(); + final String timeUnitString = event.getOption("timeunit").getAsString(); + TimeUnit timeUnit = null; + + // Check the timeUnitsString to determine the duration + switch (timeUnitString) { + case "s": + timeUnit = TimeUnit.SECONDS; + break; + case "m": + timeUnit = TimeUnit.MINUTES; + break; + case "h": + timeUnit = TimeUnit.HOURS; + break; + case "d": + timeUnit = TimeUnit.DAYS; + break; + case "w": + timeUnit = TimeUnit.DAYS; + time = time * 7; + break; + case "M": + timeUnit = TimeUnit.DAYS; + time = time * 30; + break; + default: + event.replyEmbeds(new SimpleEmbedBuilder("timeout | ERROR") + .text("You did not fil in the right time unit") + .error().build()).setEphemeral(true).queue(); + break; + } + + // Assert the option to check if the values aren't null + assert timeUnit != null; + + // Give the member a timeout + guild.getMember(target).timeoutFor(time, timeUnit).queue(); + + // Send success message the executor of the command + event.replyEmbeds(new SimpleEmbedBuilder("TimeOut | SUCCESS") + .text("You have given " + target.getAsMention() + " a timeout;", + "", + "**Reason:** " + reason, + "**Duration:** " + time + " " + timeUnit.toString().toLowerCase()) + .build()).setEphemeral(true).queue(); + + // Send dm message to the member that got a timeout + target.openPrivateChannel().complete().sendMessageEmbeds(new SimpleEmbedBuilder("Timeout | RECEIVED") + .text("You have been given an timeout!", + "", + "**Reason:** " + reason, + "**Duration:** " + time + " " + timeUnit.toString().toLowerCase()) + .build()).queue(); + + Logs.PunishLogs.log(new SimpleEmbedBuilder("Timeout | SUCCESS") + .text(target.getAsMention() + " has been given a timeout", + " ", + "**Reason:** " + reason, + "**Duration:** " + time + " " + timeUnit.toString().toLowerCase())); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/WarnCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/WarnCommand.java new file mode 100644 index 00000000..86353da9 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/staff/punishment/WarnCommand.java @@ -0,0 +1,87 @@ +package me.techscode.techdiscordbot.commands.staff.punishment; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.model.Logs; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + + +/** + * TODO: Fix all the commands and finish this file! + */ +public class WarnCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public WarnCommand() { + super("warn"); + description("Warn a user"); + + mainGuildOnly(); + + options( + new OptionData(OptionType.USER, "user", "The user to warn", true), + new OptionData(OptionType.STRING, "reason", "The reason for the warn", true) + ); + } + + /** + * The main code of the timeout command + * + * @param event SlashCommandInteractionEvent + */ + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + // Get the command sender + final User executor = event.getUser(); + + // Get the guild from the event + final Guild guild = event.getGuild(); + assert guild != null; + + final User target = event.getOption("user").getAsUser(); + final String reason = event.getOption("reason").getAsString(); + + // Get the member from the guild + final Member guildMember = guild.getMember(target); + + // Check if the target isn't null + if (guildMember == null) { + event.reply("The user is not in this guild.").setEphemeral(true).queue(); + return; + } + + // Check if the target is a staff member + if (guildMember.getRoles().contains(SimpleRoles.getRoleByName(getGuild(), "staff")) || guildMember.getRoles().contains(SimpleRoles.getRoleByName(getGuild(), "bot"))) { + event.reply("You are not allowed to warn a staff member or a BOT").setEphemeral(true).queue(); + return; + } + + event.reply("You have warned; " + target.getAsMention() + " for; `" + reason + "`").queue(); + + event.getGuildChannel().sendMessageEmbeds( + new SimpleEmbedBuilder("Warning") + .text("You have been warned by; " + executor.getAsMention()) + .field("Reason;", reason, false) + .build() + ).queue(); + + if (guild == TechDiscordBot.getMainGuild()) { + Logs.PunishLogs.log( + new SimpleEmbedBuilder("Warn | " + target.getName()) + .text("Warned a user in the guild;") + .field("Target;", target.getAsMention(), true) + .field("Staff member;", executor.getAsMention(), true) + .field("Reason;", reason, false) + ); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketCommand.java new file mode 100644 index 00000000..be1206a4 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketCommand.java @@ -0,0 +1,112 @@ +package me.techscode.techdiscordbot.commands.tickets; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlTicket; +import me.techscode.techdiscordbot.modules.TicketModule; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class TicketCommand extends SimpleSlashCommand { + + public TicketCommand() { + super("ticket"); + description("Create a ticket"); + + mainGuildOnly(); + + subCommands( + new SubcommandData("create", "Create a ticket"), + new SubcommandData("close", "Close a ticket").addOption(OptionType.STRING, "reason", "The reason for closing the ticket", true) + ); + } + + @Override + protected void onCommand(SlashCommandInteractionEvent event) { + + String subCommand = event.getSubcommandName(); + + assert subCommand != null; + if(subCommand.equals("create")) { + // Create the ticket channel + CompletableFuture future = TicketModule.ticketCreate(getMember(), getGuild(), getMember()); + + future.thenAccept(channel -> { + if (channel == null) { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Creation Failed") + .text( + "Your ticket could not be created.", + "You have reached the maximum amount of tickets you can create." + ) + .error().build()).setEphemeral(true).queue(); + return; + } + + // Send a message to the user + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Created") + .text( + "Your ticket has been created.", + "To complete the ticket creation process, please follow the steps in " + channel.getAsMention() + ) + .success().build()).setEphemeral(true).queue(); + }); + + } else if(subCommand.equals("close")) { + long channelId = event.getChannel().getIdLong(); + List sqlTickets = Database.TICKETS.get(channelId); + + if (sqlTickets.size() == 0) { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Not Found") + .text( + "This ticket does not exist in the database.", + "You will need to delete this ticket manually." + ) + .error().build()).setEphemeral(true).queue(); + return; + } + + + String reason = event.getOption("reason").getAsString(); + int length = reason.split(" ").length; + + if (length < 3) { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Not Closed") + .text( + "You have filled in a reason that is too short.", + "Please provide a reason that is longer than 3 words.", + "", + "Example reason: 'Fixed Ultra Regions FLY flag not working correctly'" + ) + .error().build()).setEphemeral(true).queue(); + return; + } + + for (SqlTicket sqlTicket : sqlTickets) { + if (sqlTicket.getChannelId() != channelId) continue; + + if (sqlTicket.getMember().getDiscordId() == event.getMember().getIdLong() || SimpleRoles.hasRole(event.getMember(), Settings.Roles.staff)) { + TicketModule.ticketClose(event.getMember(), sqlTicket, event.getTimeCreated().toEpochSecond(), reason, 30000); + event.reply("Ticket closed").setEphemeral(true).queue(message -> message.deleteOriginal().queue()); + } else { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Not Closed") + .text( + "It seems that you are not the owner of this ticket.", + "Only the ticket owner can close the ticket.", + "", + "*If you think this is a mistake, please contact a staff member.*" + ) + .error().build()).setEphemeral(true).queue(); + } + return; + } + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketStaffCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketStaffCommand.java new file mode 100644 index 00000000..0c4df80c --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/tickets/TicketStaffCommand.java @@ -0,0 +1,390 @@ +package me.techscode.techdiscordbot.commands.tickets; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.TranscriptDatabase; +import me.techscode.techdiscordbot.database.entities.SqlTicket; +import me.techscode.techdiscordbot.database.entities.SqlTranscript; +import me.techscode.techdiscordbot.model.Logs; +import me.techscode.techdiscordbot.modules.TicketModule; +import me.techscode.techdiscordbot.settings.Settings; +import me.techscode.techdiscordbot.transcripts.TicketTranscript; +import me.techscode.techdiscordbot.transcripts.TicketTranscriptOptions; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.IPermissionHolder; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionMapping; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.*; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public class TicketStaffCommand extends SimpleSlashCommand { + + public TicketStaffCommand() { + super("ticketstaff"); + + description("Manage tickets"); + + mainGuildOnly(); + + subCommands( + new SubcommandData("create", "Create a ticket for a user").addOption(OptionType.USER, "user", "The user to create a ticket for", true), + new SubcommandData("add", "Add a user to a ticket").addOption(OptionType.USER, "user", "The user that needs to be added to the ticket", true), + new SubcommandData("remove", "Remove a user from a ticket").addOption(OptionType.USER, "user", "The user that needs to be removed to the ticket", true), + new SubcommandData("transcript", "Get a transcript of a ticket"), + new SubcommandData("list", "List all tickets"), + new SubcommandData("info", "Get information about a ticket"), + new SubcommandData("rename", "Rename a ticket"), + new SubcommandData("transfer", "Transfer a ticket to another category").addOptions(new OptionData(OptionType.STRING, "category", "The category to transfer the ticket to", true).addChoice("support", "support").addChoice("development", "development").addChoice("management", "management").addChoice("greazi", "greazi").addChoice("timo", "timo").addChoice("lucifer", "lucifer").addChoice("ghost", "ghost").addChoice("fabian", "fabian").addChoice("peng", "peng").addChoice("das", "das").addChoice("opti", "opti")), + new SubcommandData("archive", "Archive a ticket"), + new SubcommandData("unarchive", "Unarchive a ticket"), + new SubcommandData("delete", "Delete a ticket") + ); + } + + @Override + protected void onCommand(@NotNull final SlashCommandInteractionEvent event) { + final String subCommand = event.getSubcommandName(); + + assert subCommand != null; + if (subCommand.equals("create")) { + // Create the ticket channel + Member createMember = event.getOption("user").getAsMember(); + CompletableFuture future = TicketModule.ticketCreate(event.getMember(), event.getGuild(), createMember); + future.thenAccept(channel -> { + if (channel == null) { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Creation Failed") + .text( + "Your ticket could not be created.", + "You have reached the maximum amount of tickets you can create." + ) + .error().build()).setEphemeral(true).queue(); + return; + } + + // Send a message to the user + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Created") + .text( + "A new ticket has been created for another user.", + "The other user will be able to follow the steps inside " + channel.getAsMention() + ) + .success().build()).setEphemeral(true).queue(); + event.getChannel().sendMessageEmbeds(new SimpleEmbedBuilder("Ticket Created") + .text( + createMember.getAsMention() + " there has been created a ticket for you.", + "Please follow the steps inside " + channel.getAsMention() + ) + .success().build()).queue(); + }); + return; + } + + TextChannel textChannel = event.getChannel().asTextChannel(); + + List sqlTickets = Database.TICKETS.get(textChannel.getIdLong()); + + if (sqlTickets.isEmpty()) { + event.replyEmbeds(new SimpleEmbedBuilder("📨 Ticket Not Found") + .text( + "This channel is not a ticket and can not be managed with this command.", + "If you think this is a mistake, please contact my developer." + ) + .error().build()).setEphemeral(true).queue(); + return; + } + + SqlTicket sqlTicket = null; + for (SqlTicket sqlTicket1 : sqlTickets) { + if (sqlTicket1.getChannelId() == textChannel.getIdLong()) sqlTicket = sqlTicket1; + } + + switch (Objects.requireNonNull(subCommand)) { + case "add" -> { + if (event.getMember().getIdLong() == event.getOption("user").getAsUser().getIdLong()) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("You cannot add yourself to a ticket.") + .error().build()).setEphemeral(true).queue(); + return; + } + for (Member member : textChannel.getMembers()) { + if (member.getIdLong() == event.getOption("user").getAsUser().getIdLong()) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This user is already inside the ticket.") + .error().build()).setEphemeral(true).queue(); + return; + } + } + Member addMember = event.getOption("user").getAsMember(); + final List permissionsAdd = new ArrayList<>( + Arrays.asList( + Permission.VIEW_CHANNEL, + Permission.MESSAGE_SEND, + Permission.MESSAGE_HISTORY, + Permission.MESSAGE_ATTACH_FILES, + Permission.MESSAGE_EMBED_LINKS, + Permission.MESSAGE_ADD_REACTION, + Permission.MANAGE_EMOJIS_AND_STICKERS + ) + ); + textChannel.getManager().putMemberPermissionOverride(addMember.getIdLong(), permissionsAdd, null).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully added " + addMember.getAsMention() + " to the ticket.") + .success().build()).setEphemeral(true).queue(); + Logs.TicketLogs.log(new SimpleEmbedBuilder("Ticket Member Added") + .text( + "**Member:** " + addMember.getAsMention(), + "**Ticket:** " + textChannel.getName() + " (" + textChannel.getId() + ")" + ) + ); + return; + } + case "remove" -> { + if (event.getMember().getIdLong() == event.getOption("user").getAsUser().getIdLong()) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("You cannot remove yourself of a ticket.") + .error().build()).setEphemeral(true).queue(); + return; + } + if (sqlTicket.getMember().getDiscordId() == event.getOption("user").getAsUser().getIdLong()) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("You cannot remove the ticket owner from there own ticket.") + .error().build()).setEphemeral(true).queue(); + return; + } + for (Member member : textChannel.getMembers()) { + if (member.getIdLong() == event.getOption("user").getAsUser().getIdLong()) { + Member removeMember = event.getOption("user").getAsMember(); + + final List permissionsRemove = new ArrayList<>( + Arrays.asList( + Permission.VIEW_CHANNEL, + Permission.MESSAGE_SEND, + Permission.MESSAGE_HISTORY, + Permission.MESSAGE_ATTACH_FILES, + Permission.MESSAGE_EMBED_LINKS, + Permission.MESSAGE_ADD_REACTION, + Permission.MANAGE_EMOJIS_AND_STICKERS + ) + ); + textChannel.getManager().putMemberPermissionOverride(removeMember.getIdLong(), null, permissionsRemove).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully removed " + removeMember.getAsMention() + " from the ticket.") + .success().build()).setEphemeral(true).queue(); + + Logs.TicketLogs.log(new SimpleEmbedBuilder("Ticket Member Removed") + .text( + "**Member:** " + removeMember.getAsMention(), + "**Ticket:** " + textChannel.getName() + " (" + textChannel.getId() + ")" + ) + ); + return; + } + } + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This user is already removed from the ticket.") + .error().build()).setEphemeral(true).queue(); + return; + } + case "transcript" -> { + TicketTranscript transcript = TicketTranscript.buildTranscript(event.getChannel().asTextChannel(), TicketTranscriptOptions.DEFAULT); + SqlTicket finalSqlTicket = sqlTicket; + transcript.build(object -> { + assert finalSqlTicket != null; + if (finalSqlTicket.getMember().getDiscordMember() != null) { + Logs.TicketLogs.log( + new SimpleEmbedBuilder("Ticket Transcript (Command)") + .text("Transcript of " + event.getChannel().getAsMention() + ": " + transcript.getUrl()) + .color(Color.ORANGE) + ); + } + + event.replyEmbeds( + new SimpleEmbedBuilder("Ticket Transcript") + .text("Transcript of " + event.getChannel().getAsMention() + ": " + transcript.getUrl()) + .color(Color.ORANGE) + .build() + ).queue(); + + TranscriptDatabase.TRANSCRIPT.add(new SqlTranscript(object.get("id").getAsString(), object.toString())); + }); + } + case "list" -> { + } + case "info" -> { + } + case "rename" -> { + } + case "transfer" -> { + OptionMapping optionMap = event.getOption("category"); + if (optionMap == null) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("You need to provide a category.") + .error().build()).setEphemeral(true).queue(); + return; + } + switch (optionMap.getAsString()) { + case "support" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.support) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the support category.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.support)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the support category.") + .success().build()).setEphemeral(true).queue(); + } + } + case "development" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.development) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the development category.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.development)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the development category.") + .success().build()).setEphemeral(true).queue(); + } + } + case "management" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.management) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the development category.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.management)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the development category.") + .success().build()).setEphemeral(true).queue(); + } + } + case "greazi" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.greazi) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Greazi.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.greazi)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Greazi.") + .success().build()).setEphemeral(true).queue(); + } + } + case "timo" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.timo) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Timo.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.timo)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Timo.") + .success().build()).setEphemeral(true).queue(); + } + } + case "lucifer" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.lucifer) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Lucifer.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.lucifer)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Lucifer.") + .success().build()).setEphemeral(true).queue(); + } + } + case "ghost" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.ghost) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Ghost.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.ghost)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Ghost.") + .success().build()).setEphemeral(true).queue(); + } + } + case "fabian" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.fabian) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Fabian.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.fabian)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Fabian.") + .success().build()).setEphemeral(true).queue(); + } + } + case "peng" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.peng) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Peng.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.peng)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Peng.") + .success().build()).setEphemeral(true).queue(); + } + } + case "das" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.das) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Das.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.das)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Das.") + .success().build()).setEphemeral(true).queue(); + } + } + case "opti" -> { + if (textChannel.getParentCategoryIdLong() == Settings.Modules.Ticket.Category.opti) { + event.replyEmbeds(new SimpleEmbedBuilder("Error") + .text("This ticket is already in the category for Opti.") + .error().build()).setEphemeral(true).queue(); + return; + } else { + textChannel.getManager().setParent(event.getJDA().getCategoryById(Settings.Modules.Ticket.Category.opti)).queue(); + event.replyEmbeds(new SimpleEmbedBuilder("Success") + .text("Successfully transferred the ticket to the category for Opti.") + .success().build()).setEphemeral(true).queue(); + } + } + } + } + case "archive" -> { + } + case "unarchive" -> { + } + case "delete" -> { + } + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CheckAccountCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CheckAccountCommand.java new file mode 100644 index 00000000..528395a2 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CheckAccountCommand.java @@ -0,0 +1,34 @@ +package me.techscode.techdiscordbot.commands.verification; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import me.techscode.techdiscordbot.model.enums.Marketplace; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + + +public class CheckAccountCommand extends SimpleSlashCommand { + + /** + * Create the check-account command with its specific settings + */ + public CheckAccountCommand() { + // Set the command + super("check-account"); + // Set the description of the command + description("Check a marketplace ID for a verified user"); + // Set to only the main guild + mainGuildOnly(); + // Set the options that can be used + options(new OptionData(OptionType.STRING, "marketplace", "The marketplace where you want to check ", true) + .addChoice("Spigot", Marketplace.SPIGOT.getId()) + .addChoice("MC-Market", Marketplace.BUILTBYBIT.getId()) + .addChoice("Polymart", Marketplace.POLYMART.getId()), + new OptionData(OptionType.INTEGER, "ID", "The member ID of that marketplace", true)); + } + + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CodeCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CodeCommand.java new file mode 100644 index 00000000..0126666d --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/commands/verification/CodeCommand.java @@ -0,0 +1,33 @@ +package me.techscode.techdiscordbot.commands.verification; + +import com.greazi.discordbotfoundation.handlers.commands.SimpleSlashCommand; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent; + +import java.util.UUID; + +public class CodeCommand extends SimpleSlashCommand { + + /** + * Create the timeout command with its specific settings + */ + public CodeCommand() { + super("code"); + description("Get a random code for verification"); + + mainGuildOnly(); + } + + @Override + protected void onCommand(final SlashCommandInteractionEvent event) { + final String code = UUID.randomUUID().toString().split("-")[0]; + + final SimpleEmbedBuilder builder = new SimpleEmbedBuilder("Manual Verification Code"); + builder.text( + "Your custom verification code is:", + "```TechManualVerification." + code + "```" + ); + + event.replyEmbeds(builder.build()).queue(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/Database.java b/src/main/java/me/TechsCode/TechDiscordBot/database/Database.java new file mode 100644 index 00000000..d63b3142 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/Database.java @@ -0,0 +1,22 @@ +package me.techscode.techdiscordbot.database; + +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.tables.*; +import org.jooq.DSLContext; + +// TODO: Check all debug and error messages from all the database files + +public class Database { + + public static DSLContext sql = TechDiscordBot.getSqlManager().getDslContext(); + + public static MembersTable MEMBERSTable = new MembersTable(); + public static Reminders REMINDERS = new Reminders(); + public static Transcripts TRANSCRIPTS = new Transcripts(); + public static Verifications VERIFICATIONS = new Verifications(); + public static Purchases PURCHASES = new Purchases(); + public static Tickets TICKETS = new Tickets(); + public static ApplicationsTable APPLICATIONSTable = new ApplicationsTable(); + public static PatreonTable PATREONTable = new PatreonTable(); + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptDatabase.java b/src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptDatabase.java new file mode 100644 index 00000000..829d1f56 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptDatabase.java @@ -0,0 +1,12 @@ +package me.techscode.techdiscordbot.database; + +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.tables.Transcripts; +import org.jooq.DSLContext; + +public class TranscriptDatabase { + + public static DSLContext sql = TechDiscordBot.getTranscriptSqlManager().getDslContext(); + + public static Transcripts TRANSCRIPT = new Transcripts(); +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptSqlManager.java b/src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptSqlManager.java new file mode 100644 index 00000000..87652909 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/TranscriptSqlManager.java @@ -0,0 +1,94 @@ +package me.techscode.techdiscordbot.database; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.debug.Debugger; +import com.greazi.discordbotfoundation.settings.SimpleSettings; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import me.techscode.techdiscordbot.settings.Settings; +import org.jooq.DSLContext; +import org.jooq.SQLDialect; +import org.jooq.impl.DSL; +import org.jooq.meta.jaxb.Generator; +import org.jooq.meta.jaxb.Jdbc; +import org.jooq.meta.jaxb.Target; + +public class TranscriptSqlManager { + + private static HikariDataSource dataSource; + private DSLContext dslContext = null; + private final String host = SimpleSettings.Database.Host(); + private final String db = "TechDiscordBot"; + private final String url = "jdbc:mysql://" + host + "/" + db; + private final String userName = Settings.Database.Transcript.username; + private final String password = Settings.Database.Transcript.password; + + public TranscriptSqlManager() { + if (!SimpleSettings.Database.Enabled()) { + Common.log("MySQL system Disabled!"); + return; + } + Common.log("Transcript Database system Enabled! Starting up Transcript MYSQL system"); + + final HikariConfig config = new HikariConfig(); + config.setMinimumIdle(5); + config.setMaximumPoolSize(15); + config.setJdbcUrl(url); + config.setUsername(userName); + config.setPassword(password); + + try { + dataSource = new HikariDataSource(config); + dslContext = DSL.using(dataSource, SQLDialect.MYSQL); + Common.log("Transcript MYSQL system Started!"); + } catch (final Exception e) { + Debugger.printStackTrace(e); + } + + if (!dataSource.isClosed()) { + Common.log("Successfully connected to Transcript MySQL database!"); + } else { + Common.log("Failed to connect to Transcript MySQL database!"); + } + } + + public void codeGenerator() { + new org.jooq.meta.jaxb.Configuration() + .withJdbc(new Jdbc() + .withDriver("com.mysql.jdbc.Driver") + .withUrl(url) + .withUser(userName) + .withPassword(password) + ) + .withGenerator( + new Generator() + .withDatabase( + new org.jooq.meta.jaxb.Database() + .withName(db) + .withIncludes(".*") + .withExcludes("" + + "UNUSED_TABLE # This table (unqualified name) should not be generated" + + "| PREFIX_.* # Objects with a given prefix should not be generated" + + "| SECRET_SCHEMA\\.SECRET_TABLE # This table (qualified name) should not be generated" + + "| SECRET_ROUTINE # This routine (unqualified name) ..." + + "" + ) + .withInputSchema("[your database schema / owner / name]") + ) + .withTarget( + new Target() + .withPackageName("com.greazi.discordbotfoundation.mysql") + .withDirectory("src/main/java/com/greazi/discordbotfoundation/mysql/generated") + ) + ); + } + + public static HikariDataSource getDataSource() { + return dataSource; + } + + public DSLContext getDslContext() { + return dslContext; + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlApplication.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlApplication.java new file mode 100644 index 00000000..1f325691 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlApplication.java @@ -0,0 +1,65 @@ +package me.techscode.techdiscordbot.database.entities; + +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.model.enums.Application; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; + +import java.util.List; + +public class SqlApplication { + + private int id; + private final int memberId; + private final long channelId; + + private final long time; + private final String category; + + public SqlApplication(final int memberId, final long channelId, final long time, final String category) { + this.memberId = memberId; + this.channelId = channelId; + this.time = time; + this.category = category; + } + + public SqlApplication(final int id, final int memberId, final long channelId, final long time, final String category) { + this.id = id; + this.memberId = memberId; + this.channelId = channelId; + this.time = time; + this.category = category; + } + + public int getId() { + return id; + } + + public List getMember() { + return Database.MEMBERSTable.getFromId(memberId); + } + + public long getChannelId() { + return channelId; + } + + public TextChannel getChannel() { + return TechDiscordBot.getMainGuild().getTextChannelById(channelId); + } + + public Long getTime() { + return time; + } + + public Application.Position getCategory() { + return Application.Position.getById(category); + } + + public void save() { + Database.APPLICATIONSTable.add(this); + } + + public void delete() { + Database.APPLICATIONSTable.remove(this.getChannelId()); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlMember.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlMember.java new file mode 100644 index 00000000..1361bbbe --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlMember.java @@ -0,0 +1,45 @@ +package me.techscode.techdiscordbot.database.entities; + +import com.greazi.discordbotfoundation.SimpleBot; +import com.greazi.discordbotfoundation.settings.SimpleSettings; +import me.techscode.techdiscordbot.database.Database; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.User; + +import java.util.Objects; + +public class SqlMember { + + private int id; + private final long discordId; + + public SqlMember(final long discordId) { + this.discordId = discordId; + } + + public SqlMember(final int id, final long discordId) { + this.id = id; + this.discordId = discordId; + } + + public int getId() { + return this.id; + } + + public long getDiscordId() { + return this.discordId; + } + + public Member getDiscordMember() { + return Objects.requireNonNull(SimpleBot.getJDA().getGuildById(SimpleSettings.Bot.MainGuild())).getMemberById(this.discordId); + } + + public User getDiscordUser() { + return SimpleBot.getJDA().getUserById(this.discordId); + } + + public void save() { + Database.MEMBERSTable.add(this); + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPatreon.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPatreon.java new file mode 100644 index 00000000..84e2acdf --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPatreon.java @@ -0,0 +1,58 @@ +package me.techscode.techdiscordbot.database.entities; + +import me.techscode.techdiscordbot.database.Database; + +import javax.annotation.Nullable; +import java.util.Optional; + +public class SqlPatreon { + private int id; + private final int memberId; + private final long join; + private long left; + private int tier; + + public SqlPatreon(final int memberId, final long join) { + this.memberId = memberId; + this.join = join; + } + + + public SqlPatreon(final int id, final int memberId, final long join, final long left, int tier) { + this.id = id; + this.memberId = memberId; + this.join = join; + this.left = left; + } + + public int getId() { + return id; + } + + @Nullable + public SqlMember getSqlMember() { + final Optional SqlMember = Database.MEMBERSTable.getFromId(this.memberId).stream().findFirst(); + return SqlMember.orElse(null); + } + + public long getJoin() { + return join; + } + + public long getLeft() { + return left; + } + + public int getTier() { + return tier; + } + + public boolean save() { + return Database.PATREONTable.add(this); + } + + public boolean delete() { + return Database.PATREONTable.delete(this); + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPreorder.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPreorder.java new file mode 100644 index 00000000..c59e94af --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlPreorder.java @@ -0,0 +1,49 @@ +package me.techscode.techdiscordbot.database.entities; + +import java.sql.Timestamp; + +public class SqlPreorder { + + private final String email; + private final long discordId; + + private final String discordName; + private final String transactionId; + private final int patreon; + + private final Timestamp lastDownload; + + public SqlPreorder(final String email, final long discordId, final String discordName, final String transactionId, final int patreon, final Timestamp lastDownload) { + this.email = email; + this.discordId = discordId; + this.discordName = discordName; + this.transactionId = transactionId; + this.patreon = patreon; + this.lastDownload = lastDownload; + } + + public String getEmail() { + return this.email; + } + + public long getDiscordId() { + return this.discordId; + } + + public String getDiscordName() { + return this.discordName; + } + + public String getTransactionId() { + return this.transactionId; + } + + public int getPatreon() { + return this.patreon; + } + + public Timestamp getLastDownload() { + return this.lastDownload; + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlReminder.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlReminder.java new file mode 100644 index 00000000..90a544b3 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlReminder.java @@ -0,0 +1,75 @@ +package me.techscode.techdiscordbot.database.entities; + +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.Database; +import net.dv8tion.jda.api.entities.Member; + +import java.time.LocalDateTime; + +public class SqlReminder { + + private int id; + private final int memberId; + private final long channelId; + private final long messageId; + private final LocalDateTime time; + private final int type; + private final String reminder; + + public SqlReminder(final int memberId, final long channelId, final long messageId, final LocalDateTime time, final int type, final String reminder) { + this.memberId = memberId; + this.channelId = channelId; + this.messageId = messageId; + this.time = time; + this.type = type; + this.reminder = reminder; + } + + public SqlReminder(final int id, final int memberId, final long channelId, final long messageId, final LocalDateTime time, final int type, final String reminder) { + this.id = id; + this.memberId = memberId; + this.channelId = channelId; + this.messageId = messageId; + this.time = time; + this.type = type; + this.reminder = reminder; + } + + public int getId() { + return id; + } + + public Member getMember() { + for (final SqlMember member : Database.MEMBERSTable.getFromId(memberId)) { + if (TechDiscordBot.getJDA().getTextChannelById(channelId).getHistory().getMessageById(messageId).getAuthor().getIdLong() == member.getDiscordId()) { + return member.getDiscordMember(); + } + } + return null; + } + + public long getChannelId() { + return channelId; + } + + public long getMessageId() { + return messageId; + } + + public LocalDateTime getTime() { + return time; + } + + public int getType() { + return type; + } + + public String getReminder() { + return reminder; + } + + public void save() { + Database.REMINDERS.add(this); + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTicket.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTicket.java new file mode 100644 index 00000000..88755fe2 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTicket.java @@ -0,0 +1,80 @@ +package me.techscode.techdiscordbot.database.entities; + +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.Database; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; + +public class SqlTicket { + + private int id; + private final long memberId; + private final long channelId; + + private final long time; + private final String category; + private final String type; + private final String priority; + + public SqlTicket(final long memberId, final long channelId, final long time, final String category, final String type, final String priority) { + this.memberId = memberId; + this.channelId = channelId; + this.time = time; + this.category = category; + this.type = type; + this.priority = priority; + } + + public SqlTicket(final int id, final long memberId, final long channelId, final long time, final String category, final String type, final String priority) { + this.id = id; + this.memberId = memberId; + this.channelId = channelId; + this.time = time; + this.category = category; + this.type = type; + this.priority = priority; + } + + public int getId() { + return id; + } + + public long getMemberId() { + return memberId; + } + + public SqlMember getMember() { + return Database.MEMBERSTable.getFromId(Integer.parseInt(memberId + "")).get(0); + } + + public long getChannelId() { + return channelId; + } + + public TextChannel getChannel() { + return TechDiscordBot.getMainGuild().getTextChannelById(channelId); + } + + public Long getTime() { + return time; + } + + public String getCategory() { + return category; + } + + public String getType() { + return type; + } + + public String getPriority() { + return priority; + } + + public void save() { + Database.TICKETS.add(this); + } + + public void delete() { + Database.TICKETS.remove(this.getChannelId()); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTranscript.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTranscript.java new file mode 100644 index 00000000..7860af5c --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/SqlTranscript.java @@ -0,0 +1,28 @@ +package me.techscode.techdiscordbot.database.entities; + +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.TranscriptDatabase; + +public class SqlTranscript { + private String id; + private final String value; + + public SqlTranscript(final String id, final String value) { + this.id = id; + this.value = value; + } + + public String getId() { + return id; + } + + public String getMessages() { + return value; + } + + public void save() { + TranscriptDatabase.TRANSCRIPT.add(this); + } + +} + diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlPurchase.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlPurchase.java new file mode 100644 index 00000000..a2679f09 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlPurchase.java @@ -0,0 +1,54 @@ +package me.techscode.techdiscordbot.database.entities.verification; + +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlMember; + +import javax.annotation.Nullable; +import java.util.Optional; + +public class SqlPurchase { + private int id; + private final int verificationId; + private final int pluginId; + private final String transactionId; + + public SqlPurchase(final int verificationId, final int pluginId, final String transactionId) { + this.verificationId = verificationId; + this.pluginId = pluginId; + this.transactionId = transactionId; + } + + public SqlPurchase(final int id, final int verificationId, final int pluginId, final String transactionId) { + this.id = id; + this.verificationId = verificationId; + this.pluginId = pluginId; + this.transactionId = transactionId; + } + + public int getId() { + return id; + } + + public int getVerificationId() { + return verificationId; + } + + @Nullable + public SqlMember getSqlMember() { + Optional sqlVerification = Database.VERIFICATIONS.getById(this.verificationId).stream().findFirst(); + return sqlVerification.map(SqlVerification::getSqlMember).orElse(null); + } + + public int getPluginId() { + return pluginId; + } + + public String getTransactionId() { + return transactionId; + } + + public void save() { + Database.PURCHASES.add(this); + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlVerification.java b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlVerification.java new file mode 100644 index 00000000..5002e06f --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/entities/verification/SqlVerification.java @@ -0,0 +1,55 @@ +package me.techscode.techdiscordbot.database.entities.verification; + +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlMember; +import me.techscode.techdiscordbot.model.enums.Marketplace; + +import javax.annotation.Nullable; +import java.util.Optional; + +public class SqlVerification { + private int id; + private final int memberId; + private final int marketplace; + private final int marketplaceUserId; + + public SqlVerification(final int memberId, final Marketplace marketplace, final int marketplaceUserId) { + this.memberId = memberId; + this.marketplace = marketplace.getId(); + this.marketplaceUserId = marketplaceUserId; + } + + public SqlVerification(final int id, final int memberId, final int marketplace, final int marketplaceUserId) { + this.id = id; + this.memberId = memberId; + this.marketplace = marketplace; + this.marketplaceUserId = marketplaceUserId; + } + + public int getId() { + return id; + } + + @Nullable + public SqlMember getSqlMember() { + final Optional SqlMember = Database.MEMBERSTable.getFromId(this.memberId).stream().findFirst(); + return SqlMember.orElse(null); + } + + public int getMarketplace() { + return marketplace; + } + + public int getMarketplaceUserId() { + return marketplaceUserId; + } + + public boolean save() { + return Database.VERIFICATIONS.add(this); + } + + public boolean delete() { + return Database.VERIFICATIONS.delete(this); + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/ApplicationsTable.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/ApplicationsTable.java new file mode 100644 index 00000000..9497e016 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/ApplicationsTable.java @@ -0,0 +1,114 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.debug.Debugger; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlApplication; +import me.techscode.techdiscordbot.model.enums.Application; +import org.jooq.Query; +import org.jooq.Select; +import org.jooq.impl.DSL; + +import java.util.List; + +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.table; +import static org.jooq.impl.SQLDataType.BIGINT; +import static org.jooq.impl.SQLDataType.VARCHAR; + +public class ApplicationsTable { + + public static final String TABLE_NAME = "applications"; + + public ApplicationsTable() { + createTable(); + } + + public void createTable() { + try { + Database.sql.createTableIfNotExists(TABLE_NAME) + .column("id", BIGINT.identity(true)).primaryKey("id") + .column("memberId", BIGINT) + .column("channelId", BIGINT) + .column("time", BIGINT) + .column("position", VARCHAR.nullable(true)) + .constraint( + DSL.foreignKey("memberId").references(MembersTable.TABLE_NAME, "id") + ) + .execute(); + Debugger.debug("Database", "Created table " + TABLE_NAME); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + } + + public void add(final SqlApplication application) { + try { + Database.sql.insertInto(table(TABLE_NAME)) + .set(field("memberId"), Database.MEMBERSTable.getFromDiscordId(application.getMember().get(0).getDiscordId()).get(0).getId()) + .set(field("channelId"), application.getChannelId()) + .set(field("time"), application.getTime()) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to add a new application to the database", + "Member ID: " + application.getMember().get(0).getDiscordId(), + "Channel ID: " + application.getChannelId(), + "Time: " + application.getTime() + ); + } + } + + public void setPosition(final long channelId, final Application.Position position) { + try { + Database.sql.update(table(TABLE_NAME)) + .set(field("position"), position.getId()) + .where(field("channelId").eq(channelId)) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to update application category in table " + TABLE_NAME); + } + } + + public List get(final int id) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("id").eq(id)); + return select.fetch().into(SqlApplication.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get application from table " + TABLE_NAME); + return null; + } + } + + public List get(final long channelId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("channelId").eq(channelId)); + return select.fetch().into(SqlApplication.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get application from table " + TABLE_NAME); + return null; + } + } + + public List getMember(final int memberId) { + try { + final Query query = Database.sql.select(field(TABLE_NAME + ".*"), field("members.*")) + .from(table("applications") + .join(table("members")) + .on(field("applications.memberId").eq(field("members.id"))) + .where(field("applications.id").eq(memberId)) + ); + return query.getBindValues(); + } catch (final Exception e) { + Common.throwError(e, "Failed to get application from table " + TABLE_NAME); + return null; + } + } + + public void remove(final long channelId) { + try { + Database.sql.deleteFrom(table(TABLE_NAME)).where(field("channelId").eq(channelId)).execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to remove application from table " + TABLE_NAME); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/MembersTable.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/MembersTable.java new file mode 100644 index 00000000..db6cd23a --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/MembersTable.java @@ -0,0 +1,80 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlMember; +import org.jooq.Select; + +import javax.annotation.Nullable; +import java.util.List; + +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.table; +import static org.jooq.impl.SQLDataType.*; + +public class MembersTable { + + public static final String TABLE_NAME = "members"; + + public MembersTable() { + createTable(); + } + + public void createTable() { + try { + Database.sql.createTableIfNotExists(TABLE_NAME) + .column("id", BIGINT.identity(true)).primaryKey("id") + .column("discordId", BIGINT) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + } + + public void add(final SqlMember member) { + try { + Database.sql.insertInto(table(TABLE_NAME)) + .set(field("discordId"), member.getDiscordId()) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to add member to table " + TABLE_NAME); + } + } + + @Nullable + public List getFromId(final int id) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("id").eq(id)); + + if (select.fetch().isEmpty()) return null; + return select.fetch().into(SqlMember.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get member from table " + TABLE_NAME); + return null; + } + } + + @Nullable + public List getFromDiscordId(final long discordId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("discordId").eq(discordId)); + if (select.fetch().isEmpty()) return null; + return select.fetch().into(SqlMember.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get member from table " + TABLE_NAME); + return null; + } + } + + @Nullable + public List getFromDiscordId(final String discordId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("discordId").eq(discordId)); + if (select.fetch().isEmpty()) return null; + return select.fetch().into(SqlMember.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get member from table " + TABLE_NAME); + return null; + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/PatreonTable.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/PatreonTable.java new file mode 100644 index 00000000..30e08406 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/PatreonTable.java @@ -0,0 +1,120 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlPatreon; +import me.techscode.techdiscordbot.model.enums.Patreon; +import org.jooq.Select; + +import java.util.List; + +import static org.jooq.impl.DSL.*; +import static org.jooq.impl.SQLDataType.BIGINT; +import static org.jooq.impl.SQLDataType.INTEGER; + +public class PatreonTable { + public static final String TABLE_NAME = "patreon"; + + public PatreonTable() { + createTable(); + } + + public void createTable() { + try { + Database.sql.createTableIfNotExists(TABLE_NAME) + .column("id", BIGINT.identity(true)).primaryKey("id") + .column("memberId", BIGINT) + .column("join", BIGINT) + .column("left", BIGINT.nullable(true)) + .column("tier", INTEGER) + .constraint( + foreignKey("memberId") + .references("members", "id") + ) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + } + + public boolean add(final SqlPatreon sqlPatreon) { + try { + Database.sql.insertInto(table(TABLE_NAME)) + .set(field("memberId"), sqlPatreon.getSqlMember().getId()) + .set(field("join"), sqlPatreon.getJoin()) + .execute(); + return true; + } catch (final Exception e) { + Common.throwError(e, "Failed to add sqlPatreon to table " + TABLE_NAME + " for member " + sqlPatreon.getSqlMember().getDiscordMember().getNickname()); + return false; + } + } + + public boolean updateTier(final int sqlMemberId, final Patreon patreon) { + try { + Database.sql.update(table(TABLE_NAME)) + .set(field("tier"), patreon.getId()) + .where(field("id").eq(sqlMemberId)) + .execute(); + return true; + } catch (final Exception e) { + Common.throwError(e, "Failed to update sqlPatreon in table " + TABLE_NAME + " for member " + sqlMemberId); + return false; + } + } + + public boolean setLeft(final SqlPatreon sqlPatreon) { + try { + Database.sql.update(table(TABLE_NAME)) + .set(field("left"), sqlPatreon.getLeft()) + .where(field("id").eq(sqlPatreon.getId())) + .execute(); + return true; + } catch (final Exception e) { + Common.throwError(e, "Failed to update sqlPatreon in table " + TABLE_NAME + " for member " + sqlPatreon.getSqlMember().getDiscordMember().getNickname()); + return false; + } + } + + public boolean delete(final SqlPatreon sqlPatreon) { + try { + Database.sql.deleteFrom(table(TABLE_NAME)) + .where(field("id").eq(sqlPatreon.getId())) + .execute(); + return true; + } catch (final Exception e) { + Common.throwError(e, "Failed to delete sqlPatreon from table " + TABLE_NAME + " for member " + sqlPatreon.getSqlMember().getDiscordMember().getNickname()); + return false; + } + } + + public List getById(final int id) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("id").eq(id)); + return select.fetch().into(SqlPatreon.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get verification from table " + TABLE_NAME + " for id " + id); + return null; + } + } + + public List getByDiscordId(final long memberId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("memberId").eq(Database.MEMBERSTable.getFromDiscordId(memberId).get(0).getId())); + return select.fetch().into(SqlPatreon.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get verification from table " + TABLE_NAME + " for discord id " + memberId); + return null; + } + } + + public List getAll() { + try { + final Select select = Database.sql.select().from(TABLE_NAME); + return select.fetch().into(SqlPatreon.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get all verifications from table " + TABLE_NAME); + return null; + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Preorders.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Preorders.java new file mode 100644 index 00000000..173a436e --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Preorders.java @@ -0,0 +1,35 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import me.techscode.techdiscordbot.database.TranscriptDatabase; +import me.techscode.techdiscordbot.database.entities.SqlPreorder; +import org.jooq.Select; + +import java.util.List; + +import static org.jooq.impl.DSL.field; + +public class Preorders { + + public static final String TABLE_NAME = "Preorders"; + + public List get(final long discordId) { + try { + final Select select = TranscriptDatabase.sql.select().from(TABLE_NAME).where(field("discordId").eq(discordId)); + return select.fetch().into(SqlPreorder.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get preorder from table " + TABLE_NAME); + return null; + } + } + + public List getAll() { + try { + final Select select = TranscriptDatabase.sql.select().from(TABLE_NAME); + return select.fetch().into(SqlPreorder.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get all preorders from table " + TABLE_NAME); + return null; + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Purchases.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Purchases.java new file mode 100644 index 00000000..36098ee2 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Purchases.java @@ -0,0 +1,90 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.verification.SqlPurchase; +import me.techscode.techdiscordbot.database.entities.verification.SqlVerification; +import org.jooq.Select; + +import java.util.List; + +import static org.jooq.impl.DSL.*; +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.SQLDataType.*; + +public class Purchases { + public static final String TABLE_NAME = "purchases"; + + public Purchases() { + createTable(); + } + + public void createTable() { + try { + Database.sql.createTableIfNotExists(TABLE_NAME) + .column("id", BIGINT.identity(true)).primaryKey("id") + .column("verificationId", BIGINT) + .column("pluginId", INTEGER) + .column("transactionId", VARCHAR) + .constraint( + foreignKey("verificationId") + .references("verifications", "id") + ) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + } + + public void add(final SqlPurchase verification) { + try { + Database.sql.insertInto(table(TABLE_NAME)) + .set(field("verificationId"), verification.getVerificationId()) + .set(field("pluginId"), verification.getPluginId()) + .set(field("transactionId"), verification.getTransactionId()) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to add a new purchase to table " + TABLE_NAME + " from member " + verification.getSqlMember().getDiscordMember().getEffectiveName() + "-" + verification.getSqlMember().getDiscordId()); + } + } + + public List getById(final int id) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("id").eq(id)); + return select.fetch().into(SqlPurchase.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get a purchase from table " + TABLE_NAME + " from id " + id); + return null; + } + } + + public List getByVerificationId(final int verificationId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("verificationId").eq(verificationId)); + return select.fetch().into(SqlPurchase.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get a purchase from table " + TABLE_NAME + " from verification id " + verificationId); + return null; + } + } + + public List getByDiscordId(final long discordId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("verificationId").eq(Database.VERIFICATIONS.getByDiscordId(discordId).get(0).getId())); + return select.fetch().into(SqlPurchase.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get verification from table " + TABLE_NAME + " from Discord id " + discordId); + return null; + } + } + + public List getByTransactionId(final long transactionId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("transactionId").eq(Database.MEMBERSTable.getFromDiscordId(transactionId).get(0).getId())); + return select.fetch().into(SqlPurchase.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get verification from table " + TABLE_NAME + " from discord id " + transactionId); + return null; + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Reminders.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Reminders.java new file mode 100644 index 00000000..0bf2528f --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Reminders.java @@ -0,0 +1,70 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlReminder; +import org.jooq.Query; +import org.jooq.impl.DSL; + +import java.util.List; + +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.table; +import static org.jooq.impl.SQLDataType.*; + +public class Reminders { + public static final String TABLE_NAME = "reminders"; + + public Reminders() { + createTable(); + } + + public void createTable() { + try { + Database.sql.createTableIfNotExists(TABLE_NAME) + .column("id", BIGINT.identity(true)).primaryKey("id") + .column("memberId", BIGINT) + .column("channelId", BIGINT) + .column("messageId", BIGINT) + .column("time", TIMESTAMP) + .column("type", INTEGER.nullable(true)) + .column("reminder", VARCHAR) + .constraint( + DSL.foreignKey("memberId").references(MembersTable.TABLE_NAME, "id") + ) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + } + + public void add(final SqlReminder reminder) { + try { + Database.sql.insertInto(table(TABLE_NAME)) + .set(field("memberId"), Database.MEMBERSTable.getFromDiscordId(reminder.getMember().getIdLong()).get(0).getId()) + .set(field("channelId"), reminder.getChannelId()) + .set(field("messageId"), reminder.getMessageId()) + .set(field("time"), reminder.getTime()) + .set(field("type"), reminder.getType()) + .set(field("reminder"), reminder.getReminder()) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to add member to table " + TABLE_NAME); + } + } + + public List getMember(final int memberId) { + try { + final Query query = Database.sql.select(field(TABLE_NAME + ".*"), field("members.*")) + .from(table("reminders") + .join(table("members")) + .on(field("reminders.memberId").eq(field("members.id"))) + .where(field("reminders.id").eq(memberId)) + ); + return query.getBindValues(); + } catch (final Exception e) { + Common.throwError(e, "Failed to get member from table " + TABLE_NAME); + return null; + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Tickets.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Tickets.java new file mode 100644 index 00000000..a5d975d2 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Tickets.java @@ -0,0 +1,161 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.debug.Debugger; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlTicket; +import me.techscode.techdiscordbot.model.enums.Ticket; +import org.jooq.Query; +import org.jooq.Select; +import org.jooq.impl.DSL; + +import java.util.List; + +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.table; +import static org.jooq.impl.SQLDataType.*; + +public class Tickets { + + public static final String TABLE_NAME = "tickets"; + + public Tickets() { + createTable(); + } + + public void createTable() { + try { + Database.sql.createTableIfNotExists(TABLE_NAME) + .column("id", BIGINT.identity(true)).primaryKey("id") + .column("memberId", BIGINT) + .column("channelId", BIGINT) + .column("time", BIGINT) + .column("category", VARCHAR.nullable(true)) + .column("type", VARCHAR.nullable(true)) + .column("priority", VARCHAR.nullable(true)) + .constraint( + DSL.foreignKey("memberId").references(MembersTable.TABLE_NAME, "id") + ) + .execute(); + Debugger.debug("Database", "Created table " + TABLE_NAME); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + } + + public void add(final SqlTicket ticket) { + try { + Database.sql.insertInto(table(TABLE_NAME)) + .set(field("memberId"), Database.MEMBERSTable.getFromDiscordId(ticket.getMemberId()).get(0).getId()) + .set(field("channelId"), ticket.getChannelId()) + .set(field("time"), ticket.getTime()) + .set(field("category"), ticket.getCategory()) + .set(field("type"), ticket.getType()) + .set(field("priority"), ticket.getPriority()) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to add a new ticket to the database", + "Member ID: " + ticket.getMemberId(), + "Channel ID: " + ticket.getChannelId(), + "Time: " + ticket.getTime() + ); + } + } + + public void setCategory(final long channelId, final Ticket.Category category) { + try { + Database.sql.update(table(TABLE_NAME)) + .set(field("category"), category.getId()) + .where(field("channelId").eq(channelId)) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to update ticket category in table " + TABLE_NAME); + } + } + + public void setType(final long channelId, final String type) { + try { + Database.sql.update(table(TABLE_NAME)) + .set(field("type"), type) + .where(field("channelId").eq(channelId)) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to update ticket in table " + TABLE_NAME); + } + } + + public void setPriority(final long channelId, final String priority) { + try { + Database.sql.update(table(TABLE_NAME)) + .set(field("priority"), priority) + .where(field("channelId").eq(channelId)) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to update ticket in table " + TABLE_NAME); + } + } + + public List get(final int id) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("id").eq(id)); + return select.fetch().into(SqlTicket.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get ticket from table " + TABLE_NAME); + return null; + } + } + + public List get(final long channelId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("channelId").eq(channelId)); + return select.fetch().into(SqlTicket.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get ticket from table " + TABLE_NAME); + return null; + } + } + + public List getFromMembedId(final long memberId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("memberId").eq(memberId)); + return select.fetch().into(SqlTicket.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get ticket from table " + TABLE_NAME); + return null; + } + } + + public List getFromMembedId(final String memberId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("memberId").eq(memberId)); + return select.fetch().into(SqlTicket.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get ticket from table " + TABLE_NAME); + return null; + } + } + + + public List getMember(final int memberId) { + try { + final Query query = Database.sql.select(field(TABLE_NAME + ".*"), field("members.*")) + .from(table("tickets") + .join(table("members")) + .on(field("tickets.memberId").eq(field("members.id"))) + .where(field("tickets.id").eq(memberId)) + ); + return query.getBindValues(); + } catch (final Exception e) { + Common.throwError(e, "Failed to get ticket from table " + TABLE_NAME); + return null; + } + } + + public void remove(final long channelId) { + try { + Database.sql.deleteFrom(table(TABLE_NAME)).where(field("channelId").eq(channelId)).execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to remove ticket from table " + TABLE_NAME); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Transcripts.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Transcripts.java new file mode 100644 index 00000000..99dc744b --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Transcripts.java @@ -0,0 +1,39 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.TranscriptDatabase; +import me.techscode.techdiscordbot.database.entities.SqlTranscript; + +import static org.jooq.impl.DSL.field; +import static org.jooq.impl.DSL.table; +import static org.jooq.impl.SQLDataType.*; + +public class Transcripts { + public static final String TABLE_NAME = "Transcripts"; + + /*public Transcripts() { + createTable(); + }*/ + /*public void createTable() { + try { + TranscriptDatabase.sql.createTableIfNotExists(TABLE_NAME) + .column("id", VARCHAR) + .column("value", LONGNVARCHAR) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + }*/ + + public void add(final SqlTranscript transcript) { + try { + TranscriptDatabase.sql.insertInto(table(TABLE_NAME)) + .set(field("id"), transcript.getId()) + .set(field("value"), transcript.getMessages()) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to add member to table " + TABLE_NAME); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Verifications.java b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Verifications.java new file mode 100644 index 00000000..73b18943 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/database/tables/Verifications.java @@ -0,0 +1,114 @@ +package me.techscode.techdiscordbot.database.tables; + +import com.greazi.discordbotfoundation.Common; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.verification.SqlVerification; +import me.techscode.techdiscordbot.model.enums.Marketplace; +import org.jooq.Select; + +import java.util.List; + +import static org.jooq.impl.DSL.*; +import static org.jooq.impl.SQLDataType.BIGINT; +import static org.jooq.impl.SQLDataType.INTEGER; + +public class Verifications { + public static final String TABLE_NAME = "verifications"; + + public Verifications() { + createTable(); + } + + public void createTable() { + try { + Database.sql.createTableIfNotExists(TABLE_NAME) + .column("id", BIGINT.identity(true)).primaryKey("id") + .column("memberId", BIGINT) + .column("marketplace", INTEGER) + .column("marketplaceUserId", INTEGER) + .constraint( + foreignKey("memberId") + .references("members", "id") + ) + .execute(); + } catch (final Exception e) { + Common.throwError(e, "Failed to create table " + TABLE_NAME); + } + } + + public boolean add(final SqlVerification verification) { + try { + Database.sql.insertInto(table(TABLE_NAME)) + .set(field("memberId"), verification.getSqlMember().getId()) + .set(field("marketplace"), verification.getMarketplace()) + .set(field("marketplaceUserId"), verification.getMarketplaceUserId()) + .execute(); + return true; + } catch (final Exception e) { + Common.throwError(e, "Failed to add verification to table " + TABLE_NAME + " for member " + verification.getSqlMember().getDiscordMember().getNickname()); + return false; + } + } + + public boolean delete(final SqlVerification verification) { + try { + Database.sql.deleteFrom(table(TABLE_NAME)) + .where(field("id").eq(verification.getId())) + .execute(); + return true; + } catch (final Exception e) { + Common.throwError(e, "Failed to delete verification from table " + TABLE_NAME + " for member " + verification.getSqlMember().getDiscordMember().getNickname()); + return false; + } + } + + public List getById(final int id) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("id").eq(id)); + return select.fetch().into(SqlVerification.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get verification from table " + TABLE_NAME + " for id " + id); + return null; + } + } + + public List getByMarketplaceUserId(final Marketplace marketplace, final int marketplaceUserId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("marketplaceUserId").eq(marketplaceUserId)).and(field("marketplace").eq(marketplace.getId())); + return select.fetch().into(SqlVerification.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get verification from table " + TABLE_NAME + " for marketplace user id " + marketplaceUserId); + return null; + } + } + + public List getByDiscordId(final long memberId) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("memberId").eq(Database.MEMBERSTable.getFromDiscordId(memberId).get(0).getId())); + return select.fetch().into(SqlVerification.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get verification from table " + TABLE_NAME + " for discord id " + memberId); + return null; + } + } + + public List getAll() { + try { + final Select select = Database.sql.select().from(TABLE_NAME); + return select.fetch().into(SqlVerification.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get all verifications from table " + TABLE_NAME); + return null; + } + } + + public List getAllFromMarketplace(Marketplace marketplace) { + try { + final Select select = Database.sql.select().from(TABLE_NAME).where(field("marketplace").eq(marketplace.getId())); + return select.fetch().into(SqlVerification.class); + } catch (final Exception e) { + Common.throwError(e, "Failed to get all verifications from table " + TABLE_NAME); + return null; + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/github/GitHubUtil.java b/src/main/java/me/TechsCode/TechDiscordBot/github/GitHubUtil.java deleted file mode 100644 index 6eb33a59..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/github/GitHubUtil.java +++ /dev/null @@ -1,65 +0,0 @@ -package me.TechsCode.TechDiscordBot.github; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import org.apache.commons.io.FileUtils; -import org.kohsuke.github.*; - -import javax.net.ssl.HttpsURLConnection; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Objects; - -public class GitHubUtil { - - private static GitHub github = null; - - public static GithubRelease getLatestRelease(String repo) { - try { - GHRepository ghrepo = Objects.requireNonNull(getGithub()).getRepository("TechsCode/" + repo); - GHRelease release = ghrepo.getLatestRelease(); - - if(release == null) return null; - - return new GithubRelease(release); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } - - public static File downloadFile(String tagName, GHAsset asset) { - InputStream is = null; - try { - HttpsURLConnection urlConn = (HttpsURLConnection) asset.getUrl().openConnection(); - urlConn.setRequestMethod("GET"); - urlConn.setRequestProperty("Authorization", "token " + TechDiscordBot.getGithubToken()); - urlConn.setRequestProperty("Accept", "application/octet-stream"); - urlConn.connect(); - is = urlConn.getInputStream(); - - FileUtils.copyInputStreamToFile(is, new File("assets", tagName + "_" + asset.getId() + ".jar")); - } catch (Exception ex) { - ex.printStackTrace(); - } finally { - try { - assert is != null; - is.close(); - } catch (Exception ex2) { - ex2.printStackTrace(); - } - } - - return new File("assets", tagName + "_" + asset.getId() + ".jar"); - } - - public static GitHub getGithub() { - try { - if(github == null) github = new GitHubBuilder().withOAuthToken(TechDiscordBot.getGithubToken()).build(); - return github; - } catch (IOException e) { - e.printStackTrace(); - return null; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/github/GithubRelease.java b/src/main/java/me/TechsCode/TechDiscordBot/github/GithubRelease.java deleted file mode 100644 index 1d9eecd2..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/github/GithubRelease.java +++ /dev/null @@ -1,36 +0,0 @@ -package me.TechsCode.TechDiscordBot.github; - -import org.kohsuke.github.GHAsset; -import org.kohsuke.github.GHRelease; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -public class GithubRelease { - - private File file = null; - private final GHRelease release; - private GHAsset asset = null; - - public GithubRelease(GHRelease release) throws IOException { - List releaseAsset = release.listAssets().toList(); - if(releaseAsset.size() > 0) { - this.asset = releaseAsset.get(0); - this.file = GitHubUtil.downloadFile(release.getTagName(), asset); - } - this.release = release; - } - - public File getFile() { - return file; - } - - public GHRelease getRelease() { - return release; - } - - public GHAsset getAsset() { - return asset; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/logs/PunishLogs.java b/src/main/java/me/TechsCode/TechDiscordBot/logs/PunishLogs.java deleted file mode 100644 index 6e92f7dd..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/logs/PunishLogs.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.TechsCode.TechDiscordBot.logs; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; - -import java.awt.*; -import java.util.Objects; - -public class PunishLogs { - - private static final long CHANNEL_ID = 873362108979490868L; - - public static boolean log(String msg) { - return sendChannel("Log", msg, null); - } - - public static boolean log(String title, String msg) { - return sendChannel(title, msg, null); - } - - public static boolean log(TechEmbedBuilder embed) { - return sendChannel(embed); - } - - public static boolean error(Exception ex) { - return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); - } - - public static boolean error(String error) { - return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); - } - - private static boolean sendChannel(TechEmbedBuilder embed) { - try { - embed.queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } - - private static boolean sendChannel(String title, String msg, Color color) { - try { - new TechEmbedBuilder(title) - .text(msg) - .color(color) - .queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/logs/RoleLogs.java b/src/main/java/me/TechsCode/TechDiscordBot/logs/RoleLogs.java deleted file mode 100644 index 43fe6324..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/logs/RoleLogs.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.TechsCode.TechDiscordBot.logs; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; - -import java.awt.*; -import java.util.Objects; - -public class RoleLogs { - - private static final long CHANNEL_ID = 873362071679533106L; - - public static boolean log(String msg) { - return sendChannel("Log", msg, null); - } - - public static boolean log(String title, String msg) { - return sendChannel(title, msg, null); - } - - public static boolean log(TechEmbedBuilder embed) { - return sendChannel(embed); - } - - public static boolean error(Exception ex) { - return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); - } - - public static boolean error(String error) { - return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); - } - - private static boolean sendChannel(TechEmbedBuilder embed) { - try { - embed.queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } - - private static boolean sendChannel(String title, String msg, Color color) { - try { - new TechEmbedBuilder(title) - .text(msg) - .color(color) - .queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/logs/ServerLogs.java b/src/main/java/me/TechsCode/TechDiscordBot/logs/ServerLogs.java deleted file mode 100644 index f047be09..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/logs/ServerLogs.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.TechsCode.TechDiscordBot.logs; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; - -import java.awt.*; -import java.util.Objects; - -public class ServerLogs { - - private static final long CHANNEL_ID = 761382066633572373L; - - public static boolean log(String msg) { - return sendChannel("Log", msg, null); - } - - public static boolean log(String title, String msg) { - return sendChannel(title, msg, null); - } - - public static boolean log(TechEmbedBuilder embed) { - return sendChannel(embed); - } - - public static boolean error(Exception ex) { - return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); - } - - public static boolean error(String error) { - return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); - } - - private static boolean sendChannel(TechEmbedBuilder embed) { - try { - embed.queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } - - private static boolean sendChannel(String title, String msg, Color color) { - try { - new TechEmbedBuilder(title) - .text(msg) - .color(color) - .queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/logs/TicketLogs.java b/src/main/java/me/TechsCode/TechDiscordBot/logs/TicketLogs.java deleted file mode 100644 index 9dfaafcc..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/logs/TicketLogs.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.TechsCode.TechDiscordBot.logs; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; - -import java.awt.*; -import java.util.Objects; - -public class TicketLogs { - - private static final long CHANNEL_ID = 873362032676716614L; - - public static boolean log(String msg) { - return sendChannel("Log", msg, null); - } - - public static boolean log(String title, String msg) { - return sendChannel(title, msg, null); - } - - public static boolean log(TechEmbedBuilder embed) { - return sendChannel(embed); - } - - public static boolean error(Exception ex) { - return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); - } - - public static boolean error(String error) { - return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); - } - - private static boolean sendChannel(TechEmbedBuilder embed) { - try { - embed.queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } - - private static boolean sendChannel(String title, String msg, Color color) { - try { - new TechEmbedBuilder(title) - .text(msg) - .color(color) - .queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/logs/TranscriptLogs.java b/src/main/java/me/TechsCode/TechDiscordBot/logs/TranscriptLogs.java deleted file mode 100644 index 3d0c9511..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/logs/TranscriptLogs.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.TechsCode.TechDiscordBot.logs; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; - -import java.awt.*; -import java.util.Objects; - -public class TranscriptLogs { - - private static final long CHANNEL_ID = 873361909909446666L; - - public static boolean log(String msg) { - return sendChannel("Log", msg, null); - } - - public static boolean log(String title, String msg) { - return sendChannel(title, msg, null); - } - - public static boolean log(TechEmbedBuilder embed) { - return sendChannel(embed); - } - - public static boolean error(Exception ex) { - return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); - } - - public static boolean error(String error) { - return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); - } - - private static boolean sendChannel(TechEmbedBuilder embed) { - try { - embed.queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } - - private static boolean sendChannel(String title, String msg, Color color) { - try { - new TechEmbedBuilder(title) - .text(msg) - .color(color) - .queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/logs/VerificationLogs.java b/src/main/java/me/TechsCode/TechDiscordBot/logs/VerificationLogs.java deleted file mode 100644 index 0439a97b..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/logs/VerificationLogs.java +++ /dev/null @@ -1,55 +0,0 @@ -package me.TechsCode.TechDiscordBot.logs; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; - -import java.awt.*; -import java.util.Objects; - -public class VerificationLogs { - - private static final long CHANNEL_ID = 873361956361359361L; - - public static boolean log(String msg) { - return sendChannel("Log", msg, null); - } - - public static boolean log(String title, String msg) { - return sendChannel(title, msg, null); - } - - public static boolean log(TechEmbedBuilder embed) { - return sendChannel(embed); - } - - public static boolean error(Exception ex) { - return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); - } - - public static boolean error(String error) { - return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); - } - - private static boolean sendChannel(TechEmbedBuilder embed) { - try { - embed.queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } - - private static boolean sendChannel(String title, String msg, Color color) { - try { - new TechEmbedBuilder(title) - .text(msg) - .color(color) - .queue(Objects.requireNonNull(TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID))); - - return true; - } catch (Exception ex) { - return false; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/Logs.java b/src/main/java/me/TechsCode/TechDiscordBot/model/Logs.java new file mode 100644 index 00000000..cf338fbf --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/Logs.java @@ -0,0 +1,328 @@ +package me.techscode.techdiscordbot.model; + +import com.greazi.discordbotfoundation.SimpleBot; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.utils.messages.MessageCreateBuilder; +import net.dv8tion.jda.api.utils.messages.MessageCreateData; + +import java.awt.*; +import java.util.Objects; + +public class Logs { + + public static class ChatLogs { + + private static final long CHANNEL_ID = Settings.Modules.Logs.chat; + + public static void log(Message message) { + MessageCreateData messageCreateData = new MessageCreateBuilder() + .setContent(message.getContentRaw()) + .build(); + TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID).sendMessage(messageCreateData).complete(); + } + + + public static boolean log(String msg) { + return sendChannel("Log", msg, null); + } + + public static boolean log(String title, String msg) { + return sendChannel(title, msg, null); + } + + public static boolean log(SimpleEmbedBuilder embed) { + return sendChannel(embed); + } + + public static boolean error(Exception ex) { + return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); + } + + public static boolean error(String error) { + return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); + } + + private static boolean sendChannel(SimpleEmbedBuilder embed) { + try { + TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID).sendMessageEmbeds(embed.build()).queue(); + + return true; + } catch (Exception ex) { + return false; + } + } + + private static boolean sendChannel(String title, String msg, Color color) { + try { + new SimpleEmbedBuilder(title) + .text(msg) + .color(color) + .queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + } + + public static class ServerLogs { + + private static final long CHANNEL_ID = Settings.Modules.Logs.server; + + public boolean log(String msg) { + return sendChannel("Log", msg, null); + } + + public static boolean log(String title, String msg) { + return sendChannel(title, msg, null); + } + + public static boolean log(SimpleEmbedBuilder embed) { + return sendChannel(embed); + } + + public static boolean error(Exception ex) { + return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); + } + + public static boolean error(String error) { + return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); + } + + private static boolean sendChannel(SimpleEmbedBuilder embed) { + try { + TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID).sendMessageEmbeds(embed.build()).queue(); + + return true; + } catch (Exception ex) { + return false; + } + } + + private static boolean sendChannel(String title, String msg, Color color) { + try { + new SimpleEmbedBuilder(title) + .text(msg) + .color(color) + .queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + } + + public static class VerificationLogs { + + private static final long CHANNEL_ID = Settings.Modules.Logs.verification; + + public static boolean log(String msg) { + return sendChannel("Log", msg, null); + } + + public static boolean log(String title, String msg) { + return sendChannel(title, msg, null); + } + + public static boolean log(SimpleEmbedBuilder embed) { + return sendChannel(embed); + } + + public static boolean error(Exception ex) { + return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); + } + + public static boolean error(String error) { + return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); + } + + private static boolean sendChannel(SimpleEmbedBuilder embed) { + try { + embed.queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + + private static boolean sendChannel(String title, String msg, Color color) { + try { + new SimpleEmbedBuilder(title) + .text(msg) + .color(color) + .queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + } + + public static class PunishLogs { + + private static final long CHANNEL_ID = Settings.Modules.Logs.punish; + + public static boolean log(String msg) { + return sendChannel("Log", msg, null); + } + + public static boolean log(String title, String msg) { + return sendChannel(title, msg, null); + } + + public static boolean log(SimpleEmbedBuilder embed) { + return sendChannel(embed); + } + + public static boolean error(Exception ex) { + return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); + } + + public static boolean error(String error) { + return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); + } + + private static boolean sendChannel(SimpleEmbedBuilder embed) { + try { + embed.queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + + private static boolean sendChannel(String title, String msg, Color color) { + try { + new SimpleEmbedBuilder(title) + .text(msg) + .color(color) + .queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + } + + public static class TicketLogs { + + private static final long CHANNEL_ID = Settings.Modules.Logs.tickets; + + public static void log(Message message) { + MessageCreateData messageCreateData = new MessageCreateBuilder() + .setContent(message.getContentRaw()) + .build(); + TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID).sendMessage(messageCreateData).complete(); + } + + + public static boolean log(String msg) { + return sendChannel("Log", msg, null); + } + + public static boolean log(String title, String msg) { + return sendChannel(title, msg, null); + } + + public static boolean log(SimpleEmbedBuilder embed) { + return sendChannel(embed); + } + + public static boolean error(Exception ex) { + return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); + } + + public static boolean error(String error) { + return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); + } + + private static boolean sendChannel(SimpleEmbedBuilder embed) { + try { + TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID).sendMessageEmbeds(embed.build()).queue(); + + return true; + } catch (Exception ex) { + return false; + } + } + + private static boolean sendChannel(String title, String msg, Color color) { + try { + new SimpleEmbedBuilder(title) + .text(msg) + .color(color) + .queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + } + + public static class RoleLogs { + + private static final long CHANNEL_ID = Settings.Modules.Logs.roles; + + public static void log(Message message) { + MessageCreateData messageCreateData = new MessageCreateBuilder() + .setContent(message.getContentRaw()) + .build(); + TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID).sendMessage(messageCreateData).complete(); + } + + + public static boolean log(String msg) { + return sendChannel("Log", msg, null); + } + + public static boolean log(String title, String msg) { + return sendChannel(title, msg, null); + } + + public static boolean log(SimpleEmbedBuilder embed) { + return sendChannel(embed); + } + + public static boolean error(Exception ex) { + return sendChannel("Error", "```" + ex.getMessage() + "```", new Color(178,34,34)); + } + + public static boolean error(String error) { + return sendChannel("Error", "```" + error + "```", new Color(178,34,34)); + } + + private static boolean sendChannel(SimpleEmbedBuilder embed) { + try { + TechDiscordBot.getJDA().getTextChannelById(CHANNEL_ID).sendMessageEmbeds(embed.build()).queue(); + + return true; + } catch (Exception ex) { + return false; + } + } + + private static boolean sendChannel(String title, String msg, Color color) { + try { + new SimpleEmbedBuilder(title) + .text(msg) + .color(color) + .queue(Objects.requireNonNull(SimpleBot.getJDA().getTextChannelById(CHANNEL_ID))); + + return true; + } catch (Exception ex) { + return false; + } + } + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/Pastebin.java b/src/main/java/me/TechsCode/TechDiscordBot/model/Pastebin.java new file mode 100644 index 00000000..0987907a --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/Pastebin.java @@ -0,0 +1,47 @@ +package me.techscode.techdiscordbot.model; + +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +public class Pastebin { + + public static String post(final String text, final boolean raw) throws IOException { + final byte[] postData = text.getBytes(StandardCharsets.UTF_8); + final int postDataLength = postData.length; + + final String requestURL = "https://paste.techscode.com/documents"; + final URL url = new URL(requestURL); + final HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); + conn.setDoOutput(true); + conn.setInstanceFollowRedirects(false); + conn.setRequestMethod("POST"); + conn.setRequestProperty("User-Agent", "Hastebin Java Api"); + conn.setRequestProperty("Content-Length", Integer.toString(postDataLength)); + conn.setUseCaches(false); + + String response = null; + final DataOutputStream wr; + try { + wr = new DataOutputStream(conn.getOutputStream()); + wr.write(postData); + final BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); + response = reader.readLine(); + } catch (final IOException e) { + e.printStackTrace(); + } + + if (response.contains("\"key\"")) { + response = response.substring(response.indexOf(":") + 2, response.length() - 2); + + final String postURL = raw ? "https://paste.techscode.com/raw/" : "https://paste.techscode.com/"; + response = postURL + response; + } + + return response; + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Application.java b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Application.java new file mode 100644 index 00000000..11af84c2 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Application.java @@ -0,0 +1,254 @@ +package me.techscode.techdiscordbot.model.enums; + + +import net.dv8tion.jda.api.entities.emoji.Emoji; +import org.jetbrains.annotations.NotNull; + +public class Application { + + public enum Position { + + SUPPORT("SUPPORT", "Support", "<:support:1055924689299587183>", "Apply for supporter position"), + DEVELOPER("DEVELOPER", "Developer", "<:PluginLab:1045068040615772221>", "Apply for developer position"), + MARKETING("MARKETING", "Marketing", "<:Creditcard:1055923718326599901>", "Apply for marketing position"), + COMMUNITY_HELPER("COMMUNITY_HELPER", "Community helper", "📝", "Apply for community helper position"); + + final String id; + final String name; + final String emoji; + final String description; + + Position(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + + public static Position getById(String id) { + for (Position position : Position.values()) { + if (position.getId().equals(id)) { + return position; + } + } + return null; + } + } + + public enum Payment { + + PAYPAL("PAYPAL", "PayPal", "<:paypal:1063462219771301948>", "Get help for PayPal payments"), + MARKETPLACE("MARKETPLACE", "Marketplace", "<:support:1055924689299587183>", "Get help for Marketplace payments"), + OTHER("OTHER", "Other", "❔", "Get help for something else"); + + final String id; + final String name; + final String emoji; + final String description; + + Payment(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Developer { + + API("API", "API", "<:PluginLab:1045068040615772221>", "Get help with our API's"), + PLUGIN("PLUGIN", "Plugin", "🧑🏻‍💻", "Get help with plugin compatibility"), + OTHER("OTHER", "Other", "❔", "Get help for something else"); + + final String id; + final String name; + final String emoji; + final String description; + + Developer(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Giveaway { + + CLAIM("CLAIM", "Claim", "🎉", "Claim a giveaway"), + HOST("HOST", "Host", "🛰️", "Host a giveaway"); + + final String id; + final String name; + final String emoji; + final String description; + + Giveaway(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Patreon { + + PERKS("PERKS", "Perks", "<:patreon:1055927571885330472>", "Get help for your Patreon perks"), + REWARDS("REWARDS", "Rewards", "🎉", "Get help for your Patreon rewards"), + SUPPORT("SUPPORT", "Support", "<:support:1055924689299587183>", "Get help for your Patreon support"), + OTHER("OTHER", "Other", "❔", "Get help for something else"); + + final String id; + final String name; + final String emoji; + final String description; + + Patreon(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Priority { + + HIGH("HIGH", "High", "<:high_priority:694648884332331008>"), + MEDIUM("MEDIUM", "Medium", "<:medium_priority:694648883980009593>"), + LOW("LOW", "Low", "<:low_priority:694648884353433601>"), + NONE("NONE", "None", "<:offline:496493395187990538>"); + + final String id; + final String name; + final String emoji; + + Priority(final String id, final String name, final String emoji) { + this.id = id; + this.name = name; + this.emoji = emoji; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Marketplace.java b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Marketplace.java new file mode 100644 index 00000000..4f97d289 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Marketplace.java @@ -0,0 +1,70 @@ +package me.techscode.techdiscordbot.model.enums; + +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Role; + +public enum Marketplace { + + SPIGOT(1, "Spigot", "https://spigotmc.org", SimpleRoles.getRoleById(TechDiscordBot.getMainGuild(), Settings.Roles.spigot), "spigotmc"), + BUILTBYBIT(2, "BuiltByBit", "https://builtbybit.com", SimpleRoles.getRoleById(TechDiscordBot.getMainGuild(), Settings.Roles.builtByBit), "mcmarket"), + SONGODA(3, "Songoda", "https://marketplace.songoda.com", SimpleRoles.getRoleById(TechDiscordBot.getMainGuild(), Settings.Roles.songoda)), + POLYMART(4, "Polymart", "https://polymart.org", SimpleRoles.getRoleById(TechDiscordBot.getMainGuild(), Settings.Roles.polymart), "polymart"); + + final int id; + final String name; + final String url; + final Role role; + final String paypalApi; + + Marketplace(final int id, final String name, final String url, Role role) { + this.id = id; + this.name = name; + this.url = url; + this.role = role; + this.paypalApi = null; + } + + Marketplace(final int id, final String name, final String url, Role role, String paypalApi) { + this.id = id; + this.name = name; + this.url = url; + this.role = role; + this.paypalApi = paypalApi; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } + + public String getUrl() { + return url; + } + + public Role getRole() { + return role; + } + + public String getPaypalApi() { + return paypalApi; + } + + public static Marketplace getFromId(final int id) { + for (final Marketplace marketplace : values()) { + if (marketplace.getId() == id) { + return marketplace; + } + } + return null; + } + + public static Marketplace getFromId(final String id) { + int idInt = Integer.parseInt(id); + return getFromId(idInt); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Patreon.java b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Patreon.java new file mode 100644 index 00000000..c59f6a30 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Patreon.java @@ -0,0 +1,25 @@ +package me.techscode.techdiscordbot.model.enums; + +public enum Patreon { + + TRAVELER(1, "Traveler"), + ADVANTURER(2, "Advanturer"), + PIONEER(3, "Pioneer"), + WIZARD(4, "Wizard"); + + private int id; + private String name; + + Patreon(int id, String name) { + this.id = id; + this.name = name; + } + + public int getId() { + return id; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Plugin.java b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Plugin.java new file mode 100644 index 00000000..9ba82715 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Plugin.java @@ -0,0 +1,152 @@ +package me.techscode.techdiscordbot.model.enums; + +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public enum Plugin { + + ULTRA_PERMISSIONS(1, "Ultra Permissions", "ultrapermissions", "Uperms", "<:UltraPermissions:576937960176353293>", Settings.Roles.ultraPermissions), + ULTRA_CUSTOMIZER(2, "Ultra Customizer", "ultracustomizer", "UC", "<:UltraCustomizer:576873108506411018>", Settings.Roles.ultraCustomizer), + ULTRA_PUNISHMENTS(3, "Ultra Punishments", "ultrapunishments", "UPun", "<:UltraPunishments:576873108422524954>", Settings.Roles.ultraPunishments), + ULTRA_REGIONS(4, "Ultra Regions", "ultraregions", "UR", "<:UltraRegions:639288786236473354>", Settings.Roles.ultraRegions), + ULTRA_ECONOMY(5, "Ultra Economy", "ultraeconomy", "UE", "<:UltraEconomy:748004373971337216>", Settings.Roles.ultraEconomy), + ULTRA_SCOREBOARDS(6, "Ultra Scoreboards", "ultrascoreboards", "UBoards", "<:UltraScoreboards:843611772481044520>", Settings.Roles.ultraScoreboards), + ULTRA_MOTD(7, "Ultra Motd", "ultramotd", "UMotd", "<:UltraMotd:947812638509912105>", Settings.Roles.ultraMotd), + INSANE_SHOPS(8, "Insane Shops", "insaneshops", "IShops", "<:InsaneShops:576871756816449536>", Settings.Roles.insaneShops), + INSANE_VAULTS(9, "Insane Vaults", "insanevaults", "IVaults", "<:InsaneVaults:1059878327839621243>", Settings.Roles.insaneVaults), + INSANE_ANNOUNCER(10, "Insane Announcer", "insaneannouncer", "IAnnouncer", "<:InsaneAnnouncer:741465636231970886>"); + + final int id; + final String name; + final String lowerName; + final String shortName; + final String emoji; + final long roleId; + + Plugin(final int id, final String name, final String lowerName, final String shortName, final String emoji) { + this(id, name, lowerName, shortName, emoji, 0); + } + + Plugin(final int id, final String name, final String lowerName, final String shortName, final String emoji, final long roleId) { + this.id = id; + this.name = name; + this.lowerName = lowerName; + this.shortName = shortName; + this.emoji = emoji; + this.roleId = roleId; + } + + public int getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getLowerName() { + return this.lowerName; + } + + public String getShortName() { + return this.shortName; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + + public Role getRole() { + return SimpleRoles.getRoleById(TechDiscordBot.getMainGuild(), this.roleId); + } + + @Nullable + public static Plugin getPluginById(final int id) { + for (final Plugin plugin : values()) { + if (plugin.getId() == id) return plugin; + } + + return null; + } + + @Nullable + public static Plugin getPluginByName(final String name) { + for (final Plugin plugin : values()) { + if (plugin.getName().equalsIgnoreCase(name)) return plugin; + } + + return null; + } + + public static Plugin getPluginByLowerName(final String lowerName) { + for (final Plugin plugin : values()) { + if (plugin.getLowerName().equalsIgnoreCase(lowerName)) return plugin; + } + + return null; + } + + @Nullable + public static Plugin getPluginByShortName(final String shortName) { + for (final Plugin plugin : values()) { + if (plugin.getShortName().equalsIgnoreCase(shortName)) return plugin; + } + + return null; + } + + @Nullable + public static Plugin getPluginByRole(final Role role) { + for (final Plugin plugin : values()) { + if (plugin.getRole() != null && plugin.getRole().equals(role)) return plugin; + } + + return null; + } + + @Nullable + public static Plugin getPluginByEmoji(final String emoji) { + for (final Plugin plugin : values()) { + if (plugin.getEmojiRaw().equalsIgnoreCase(emoji)) return plugin; + } + + return null; + } + + @Nullable + public static Plugin getPluginByEmoji(final Emoji emoji) { + for (final Plugin plugin : values()) { + if (plugin.getEmoji().equals(emoji)) return plugin; + } + + return null; + } + + public static List getOwnedPlugins(Member member) { + List ownedPlugins = new ArrayList<>(); + + SimpleRoles.getAllMemberRoles(member).stream().filter(role -> getPluginByRole(role) != null).forEach(role -> { + Plugin plugin = getPluginByRole(role); + if (plugin != null) { + ownedPlugins.add(plugin); + } + }); + + return ownedPlugins; + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Ticket.java b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Ticket.java new file mode 100644 index 00000000..880fb197 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/enums/Ticket.java @@ -0,0 +1,248 @@ +package me.techscode.techdiscordbot.model.enums; + + +import net.dv8tion.jda.api.entities.emoji.Emoji; +import org.jetbrains.annotations.NotNull; + +public class Ticket { + + public enum Category { + + PLUGIN("PLUGIN", "Plugin Support", "<:support:1055924689299587183>", "Get support for a plugin"), + PAYMENTS("PAYMENTS", "Payments", "<:Creditcard:1055923718326599901>", "Get help for payments"), + DEVELOPER("DEVELOPER", "Developer Request", "<:PluginLab:1045068040615772221>", "Get help with our API's and plugin compatibility"), + GIVEAWAY("GIVEAWAY", "Giveaway", "🎉", "Claim or host a giveaway"), + PATREON("PATREON", "Patreon", "<:patreon:1055927571885330472>", "Get help for your Patreon perks"), + OTHER("OTHER", "Other", "❔", "Get help for something else"); + + final String id; + final String name; + final String emoji; + final String description; + + Category(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Payment { + + PAYPAL("PAYPAL", "PayPal", "<:paypal:1063462219771301948>", "Get help for PayPal payments"), + MARKETPLACE("MARKETPLACE", "Marketplace", "<:support:1055924689299587183>", "Get help for Marketplace payments"), + VERIFICATION("VERIFICATION", "Verification", "🔓", "Verify purchases"), + OTHER("OTHER", "Other", "❔", "Get help for something else"); + + final String id; + final String name; + final String emoji; + final String description; + + Payment(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Developer { + + API("API", "API", "<:PluginLab:1045068040615772221>", "Get help with our API's"), + PLUGIN("PLUGIN", "Plugin", "🧑🏻‍💻", "Get help with plugin compatibility"), + OTHER("OTHER", "Other", "❔", "Get help for something else"); + + final String id; + final String name; + final String emoji; + final String description; + + Developer(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Giveaway { + + CLAIM("CLAIM", "Claim", "🎉", "Claim a giveaway"), + HOST("HOST", "Host", "🛰️", "Host a giveaway"); + + final String id; + final String name; + final String emoji; + final String description; + + Giveaway(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Patreon { + + PERKS("PERKS", "Perks", "<:patreon:1055927571885330472>", "Get help for your Patreon perks"), + REWARDS("REWARDS", "Rewards", "🎉", "Get help for your Patreon rewards"), + OTHER("OTHER", "Other", "❔", "Get help for something else"); + + final String id; + final String name; + final String emoji; + final String description; + + Patreon(final String id, final String name, final String emoji, final String description) { + this.id = id; + this.name = name; + this.emoji = emoji; + this.description = description; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + public String getDescription() { + return this.description; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + } + + public enum Priority { + + HIGH("HIGH", "High", "<:high_priority:694648884332331008>"), + MEDIUM("MEDIUM", "Medium", "<:medium_priority:694648883980009593>"), + LOW("LOW", "Low", "<:low_priority:694648884353433601>"), + PATREON("PATREON", "Patreon", "<:patreon:1055927571885330472>"), + NONE("NONE", "None", "<:offline:496493395187990538>"); + + final String id; + final String name; + final String emoji; + + Priority(final String id, final String name, final String emoji) { + this.id = id; + this.name = name; + this.emoji = emoji; + } + + public String getId() { + return this.id; + } + + public String getName() { + return this.name; + } + + @NotNull + public Emoji getEmoji() { + return Emoji.fromFormatted(this.emoji); + } + + public String getEmojiRaw() { + return this.emoji; + } + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/reminders/HumanTimeBuilder.java b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/HumanTimeBuilder.java similarity index 86% rename from src/main/java/me/TechsCode/TechDiscordBot/reminders/HumanTimeBuilder.java rename to src/main/java/me/TechsCode/TechDiscordBot/model/reminders/HumanTimeBuilder.java index a0f2db7b..c0c76051 100644 --- a/src/main/java/me/TechsCode/TechDiscordBot/reminders/HumanTimeBuilder.java +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/HumanTimeBuilder.java @@ -1,6 +1,6 @@ -package me.TechsCode.TechDiscordBot.reminders; +package me.techscode.techdiscordbot.model.reminders; -import me.TechsCode.TechDiscordBot.util.ProjectUtil; +import me.techscode.techdiscordbot.utils.ProjectUtil; public class HumanTimeBuilder { @@ -44,19 +44,19 @@ public void addX(ReminderTimeType type, int amount) { public String toString() { StringBuilder sb = new StringBuilder(); - if(years > 0) + if (years > 0) sb.append(years).append(" year").append(plural(years, true)); - if(months > 0) + if (months > 0) sb.append(months).append(" month").append(plural(months, true)); - if(weeks > 0) + if (weeks > 0) sb.append(weeks).append(" week").append(plural(weeks, true)); - if(days > 0) + if (days > 0) sb.append(days).append(" day").append(plural(days, true)); - if(hours > 0) + if (hours > 0) sb.append(hours).append(" hour").append(plural(hours, true)); - if(minutes > 0) + if (minutes > 0) sb.append(minutes).append(" minute").append(plural(minutes, true)); - if(seconds > 0) + if (seconds > 0) sb.append(seconds).append(" second").append(plural(seconds, false)); String string = sb.toString(); @@ -68,7 +68,7 @@ public String toString() { } public String plural(int am, boolean space) { - if(am == 1) return (space ? ", " : "."); + if (am == 1) return (space ? ", " : "."); return "s" + (space ? ", " : "."); } diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/Reminder.java b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/Reminder.java new file mode 100644 index 00000000..31897ce8 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/Reminder.java @@ -0,0 +1,83 @@ +package me.techscode.techdiscordbot.model.reminders; + +import me.techscode.techdiscordbot.TechDiscordBot; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; + +public class Reminder { + + private final String userId, channelId, humanTime, reminder; + private final long time; + private final ReminderType type; + + public Reminder(final String userId, final String channelId, final long time, final String humanTime, final ReminderType type, final String reminder) { + this.userId = userId; + this.channelId = channelId; + this.time = time; + this.humanTime = humanTime; + this.type = (channelId == null ? ReminderType.DMs : type); + this.reminder = reminder; + } + + public String getUserId() { + return userId; + } + + public String getChannelId() { + return channelId; + } + + public long getTime() { + return time; + } + + public String getHumanTime() { + return humanTime; + } + + public ReminderType getType() { + return type; + } + + public String getReminder() { + return reminder; + } + + /*public void delete() throws SQLException { + Database.Reminders.remove(this); + }*/ + + public void send() { + final User user = TechDiscordBot.getJDA().getUserById(userId); + + if (user != null) { + ReminderType type = this.type; + final TextChannel channel = TechDiscordBot.getJDA().getTextChannelById(channelId); + + if (channel == null) type = ReminderType.DMs; + + if (type == ReminderType.DMs) { + try { + user.openPrivateChannel().queue(msg -> msg.sendMessage("**Reminder**: " + reminder).queue()); + } catch (final Exception ex) { + if (channel == null) + return; + + sendReminder(user, channel); + } + } else { + sendReminder(user, channel); + } + } + + /*try { + delete(); + } catch (final SQLException ex) { + ex.printStackTrace(); + }*/ + } + + private void sendReminder(final User user, final TextChannel channel) { + channel.sendMessage("**Reminder for " + user.getAsMention() + "**: " + reminder).queue(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderArgResponse.java b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderArgResponse.java similarity index 90% rename from src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderArgResponse.java rename to src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderArgResponse.java index b6e7aaa9..a8f2e828 100644 --- a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderArgResponse.java +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderArgResponse.java @@ -1,4 +1,4 @@ -package me.TechsCode.TechDiscordBot.reminders; +package me.techscode.techdiscordbot.model.reminders; public class ReminderArgResponse { diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderManager.java b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderManager.java new file mode 100644 index 00000000..5021f998 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderManager.java @@ -0,0 +1,110 @@ +package me.techscode.techdiscordbot.model.reminders; + +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import org.jetbrains.annotations.NotNull; + +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class ReminderManager { + + private final List reminders = new ArrayList<>(); + + // TODO: Fix this part with @Faab as it doesn't work right now! + public void load() throws SQLException { + /*final List data = Database.Reminders.get(); + + assert data != null; + this.reminders.addAll(data);*/ + + checkForReminders(); + } + + private void checkForReminders() { + final Thread thread = new Thread(() -> { + while (true) { + for (final Reminder reminder : new ArrayList<>(reminders)) { + if (Math.abs(System.currentTimeMillis() - reminder.getTime()) < 100L) { + reminder.send(); + reminders.remove(reminder); + } + } + } + }); + thread.setName("ReminderModule-" + thread.getId()); + thread.start(); + } + + public List getReminders() { + return this.reminders; + } + + public List getRemindersByUser(final User user) { + return this.reminders.stream().filter(reminder -> reminder.getUserId().equals(user.getId())).collect(Collectors.toList()); + } + + public Reminder createReminder(final User user, final String time, final String remind, final TextChannel channel, final Boolean isPrivate) { + final ReminderArgResponse argResponse = argsToTime(time.split(" ")); + if (argResponse == null) return null; + + if (argResponse.getAmountOfArgs() == 0) { + return null; + } else { + List reminder = new ArrayList<>(Arrays.asList(remind.split(" "))); + + if (reminder.size() == 0) return null; + + final Reminder reminder1 = new Reminder(user.getId(), channel.getId(), argResponse.getTime(), argResponse.getTimeHuman(), (isPrivate ? ReminderType.DMs : ReminderType.CHANNEL), String.join(" ", reminder)); + this.reminders.add(reminder1); + + /*try { + Database.Reminders.add(reminder1); + } catch (final SQLException e) { + e.printStackTrace(); + }*/ + return reminder1; + } + } + + public ReminderArgResponse argsToTime(@NotNull final String[] args) { + final HumanTimeBuilder bhb = new HumanTimeBuilder(); + long time = System.currentTimeMillis(); + int argsAm = 0; + int i = 0; + + for (final String arg : args) { + for (final ReminderTimeType rtt : ReminderTimeType.values()) { + if (Arrays.stream(rtt.getNames()).anyMatch(n -> n.equalsIgnoreCase(arg))) { + if (i > 0) { + final String tim = args[i - 1]; + try { + final int timint = Math.abs(Integer.parseInt(tim)); + time = time + rtt.toMilli(timint); + bhb.addX(rtt, timint); + argsAm = argsAm + 2; + } catch (final Exception e) { + e.printStackTrace(); + return null; + } + } + } + } + i++; + } + + return new ReminderArgResponse(time, argsAm, bhb.toString()); + } + + public void deleteReminder(final Reminder reminder) { + /*try { + reminder.delete(); + } catch (final SQLException e) { + e.printStackTrace(); + }*/ + this.reminders.remove(reminder); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderTimeType.java b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderTimeType.java new file mode 100644 index 00000000..23dcad37 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderTimeType.java @@ -0,0 +1,40 @@ +package me.techscode.techdiscordbot.model.reminders; + +import java.util.concurrent.TimeUnit; + +public enum ReminderTimeType { + + YEAR(TimeUnit.DAYS, 365, "year", "years"), + MONTH(TimeUnit.DAYS, 31, "months", "month"), + WEEK(TimeUnit.DAYS, 7, "week", "weeks", "w"), + DAY(TimeUnit.DAYS, 1, "day", "days", "d"), + HOUR(TimeUnit.HOURS, 1, "hr", "hour", "hours", "hour", "h"), + MINUTE(TimeUnit.MINUTES, 1, "min", "mins", "minutes", "minute", "m"), + SECOND(TimeUnit.SECONDS, 1, "sec", "secs", "seconds", "second", "s"); + + private final String[] names; + private final int multiplier; + private final TimeUnit timeUnit; + + ReminderTimeType(final TimeUnit unit, final int multiplier, final String... names) { + this.names = names; + this.multiplier = multiplier; + this.timeUnit = unit; + } + + public long toMilli(final int am) { + return timeUnit.toMillis(am) * multiplier; + } + + public int getMultiplier() { + return multiplier; + } + + public TimeUnit getTimeUnit() { + return timeUnit; + } + + public String[] getNames() { + return names; + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderType.java b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderType.java similarity index 77% rename from src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderType.java rename to src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderType.java index da7add62..b1c8cac1 100644 --- a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderType.java +++ b/src/main/java/me/TechsCode/TechDiscordBot/model/reminders/ReminderType.java @@ -1,4 +1,4 @@ -package me.TechsCode.TechDiscordBot.reminders; +package me.techscode.techdiscordbot.model.reminders; public enum ReminderType { diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/CommandCategory.java b/src/main/java/me/TechsCode/TechDiscordBot/module/CommandCategory.java deleted file mode 100644 index 34e494d0..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/CommandCategory.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.TechsCode.TechDiscordBot.module; - -public enum CommandCategory { - - ADMIN, FUN, INFO - -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/CommandModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/CommandModule.java deleted file mode 100644 index d868a7a1..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/CommandModule.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.TechsCode.TechDiscordBot.module; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.objects.Cooldown; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.HashMap; - -public abstract class CommandModule { - - private final HashMap cooldowns = new HashMap<>(); - protected TechDiscordBot bot; - - public CommandModule(TechDiscordBot bot) { - this.bot = bot; - } - - public abstract String getName(); - - public abstract String getDescription(); - - public abstract CommandPrivilege[] getCommandPrivileges(); - - public abstract OptionData[] getOptions(); - - public abstract int getCooldown(); - - public HashMap getCooldowns() { - return cooldowns; - } - - public abstract void onCommand(TextChannel channel, Member m, SlashCommandEvent e); - -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/Module.java b/src/main/java/me/TechsCode/TechDiscordBot/module/Module.java deleted file mode 100644 index 23364e51..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/Module.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.TechsCode.TechDiscordBot.module; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.ConsoleColor; - -import java.util.Arrays; -import java.util.Set; -import java.util.stream.Collectors; - -public abstract class Module { - - protected TechDiscordBot bot; - - private boolean enabled; - - public Module(TechDiscordBot bot) { - this.bot = bot; - } - - public void enable() { - Set failedRequirements = Arrays.stream(getRequirements()).filter(requirement -> !requirement.check()).collect(Collectors.toSet()); - if(failedRequirements.isEmpty()) { - //TechDiscordBot.log("Enabling Module " + getName() + ".."); - onEnable(); - enabled = true; - } else { - TechDiscordBot.log(ConsoleColor.YELLOW_BRIGHT + "Failed Enabling Module " + ConsoleColor.YELLOW_BOLD_BRIGHT + getName() + ConsoleColor.YELLOW_BRIGHT + " because:"); - failedRequirements.forEach(requirement -> TechDiscordBot.log(ConsoleColor.WHITE + "- " + requirement.getUnmatchMessage())); - } - } - - public abstract void onEnable(); - - public abstract void onDisable(); - - public abstract String getName(); - - public abstract Requirement[] getRequirements(); - - public boolean isEnabled() { - return enabled; - } - - public boolean isDisabled() { - return !enabled; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/ModulesManager.java b/src/main/java/me/TechsCode/TechDiscordBot/module/ModulesManager.java deleted file mode 100644 index 18819dc5..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/ModulesManager.java +++ /dev/null @@ -1,129 +0,0 @@ -package me.TechsCode.TechDiscordBot.module; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.objects.Cooldown; -import me.TechsCode.TechDiscordBot.util.ProjectUtil; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.CommandData; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.build.SubcommandData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; -import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class ModulesManager { - - private final List cmdModules = new ArrayList<>(); - private final List modules = new ArrayList<>(); - - public void load() { - TechDiscordBot.getJDA().updateCommands().queue(); - CommandListUpdateAction commands = TechDiscordBot.getGuild().updateCommands(); - - for (Class each : ProjectUtil.getClasses("me.TechsCode.TechDiscordBot.module")) { - if (CommandModule.class.isAssignableFrom(each) && !Modifier.isAbstract(each.getModifiers())) { - try { - CommandModule module = (CommandModule)each.getConstructor(TechDiscordBot.class).newInstance(TechDiscordBot.getBot()); - if(module.getName() == null) - continue; - - cmdModules.add(module); - - CommandData cmdData = new CommandData(module.getName(), module.getDescription() == null ? "No description set." : module.getDescription()) - .addOptions(module.getOptions()) - .setDefaultEnabled(module.getCommandPrivileges().length == 0); - - commands.addCommands(cmdData); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } else if (Module.class.isAssignableFrom(each) && !Modifier.isAbstract(each.getModifiers())) { - try { - Module module = (Module) each.getConstructor(TechDiscordBot.class).newInstance(TechDiscordBot.getBot()); - module.enable(); - - modules.add(module); - } catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) { - e.printStackTrace(); - } - } - } - - commands.addCommands( - new CommandData("ticket", "Manage tickets.") - .addSubcommands( - new SubcommandData("add", "Add a member to a ticket.") - .addOptions( - new OptionData(OptionType.USER, "member", "Member to add.", true) - ), - new SubcommandData("remove", "Remove a member from a ticket.") - .addOptions( - new OptionData(OptionType.USER, "member", "Member to remove.", true) - ), - new SubcommandData("transcript", "Force make a ticket transcript."), - new SubcommandData("close", "Close a ticket.") - .addOptions( - new OptionData(OptionType.STRING, "reason", "Reason to close the ticket. (Optional)") - ) - ) - ).queue(cmds -> { - cmds.forEach(command -> { - CommandPrivilege[] privilege = cmdModules.stream().filter(c -> c.getName().equals(command.getName())).map(CommandModule::getCommandPrivileges).findFirst().orElse(new CommandPrivilege[]{}); - - if (privilege.length > 0) - TechDiscordBot.getGuild().updateCommandPrivilegesById(command.getId(), Arrays.asList(privilege)).queue(); - }); - }); - - TechDiscordBot.getJDA().addEventListener(modules.toArray()); - TechDiscordBot.getJDA().addEventListener(cmdModules.toArray()); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> modules.forEach(Module::onDisable))); - } - - public void logLoad() { - int successfulAmountModules = (int)modules.stream().filter(Module::isEnabled).count(); - - TechDiscordBot.log("Modules:"); - TechDiscordBot.log(" » All: " + (modules.size() + cmdModules.size())); - TechDiscordBot.log(" » Modules: " + modules.size()); - TechDiscordBot.log(" » Command: " + cmdModules.size()); - TechDiscordBot.log(" » Success: " + successfulAmountModules); - } - - @SubscribeEvent - public void onSlashCommand(SlashCommandEvent e) { - CommandModule cmd = cmdModules.stream().filter(c -> c.getName().equalsIgnoreCase(e.getName())).findFirst().orElse(null); - if(cmd == null || e.getMember() == null || e.getUser().isBot()) - return; - - if(cmd.getCooldown() > 0 && cmd.getCooldowns().containsKey(e.getMember().getId())) { - Cooldown cooldown = cmd.getCooldowns().get(e.getMember().getId()); - if(cooldown.isCooldownRemaining()) { - e.deferReply(true).queue(); - - e.reply("**Woah there... slow down!** There's still **" + cooldown.getRemainingCooldown() + "** seconds left on your cooldown!").queue(); - return; - } - - cmd.getCooldowns().remove(e.getMember().getId()); - } - - cmd.onCommand(e.getTextChannel(), e.getMember(), e); - } - - public List getModules() { - return modules; - } - - public List getCommandModules() { - return cmdModules; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/APICommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/APICommand.java deleted file mode 100644 index b3239807..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/APICommand.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class APICommand extends CommandModule { - - public APICommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { return "api"; } - - @Override - public String getDescription() { - return "Returns the api website!"; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://api.techscode.com/").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/AddonCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/AddonCommand.java deleted file mode 100644 index 4a2b746e..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/AddonCommand.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class AddonCommand extends CommandModule { - - public AddonCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { return "addons"; } - - @Override - public String getDescription() { - return "Get the addons website."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://ultraadditions.com/").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/BanCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/BanCommand.java deleted file mode 100644 index 164953de..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/BanCommand.java +++ /dev/null @@ -1,103 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.logs.PunishLogs; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.Objects; - -public class BanCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getRoles("Staff"); } - }; - - public BanCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "ban"; - } - - @Override - public String getDescription() { - return "Ban a member from this guild."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.USER, "member", "The member to ban.", true), - new OptionData(OptionType.STRING, "reason", "The reason to ban the member.", true) - }; - } - - @Override - public int getCooldown() { - return 0; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - Member member = Objects.requireNonNull(e.getOption("member")).getAsMember(); - String reason = Objects.requireNonNull(e.getOption("reason")).getAsString(); - - Member selfMember = Objects.requireNonNull(e.getGuild()).getSelfMember(); - if (member != null && !selfMember.canInteract(member)) { - e.reply("This user is too powerful for me to ban.").queue(); - return; - } - - assert member != null; - if (member.getRoles().contains(STAFF_ROLE.query().first())) { - e.replyEmbeds( - new TechEmbedBuilder("Ban - Error") - .error() - .text("You cannot ban this user") - .build() - ).queue(); - - } else if (member == e.getMember()) { - e.replyEmbeds( - new TechEmbedBuilder("Ban - Error") - .error() - .text("You cannot ban yourself") - .build() - ).queue(); - - } else { - member.ban(0, reason).queue(); - - e.replyEmbeds( - new TechEmbedBuilder("Banned " + member.getUser().getName() + "#" + member.getUser().getDiscriminator()) - .success() - .text("Successfully banned " + member.getAsMention() + " for `" + reason + "`!") - .build() - ).queue(); - - PunishLogs.log( - new TechEmbedBuilder("Banned " + member.getUser().getName() + "#" + member.getUser().getDiscriminator()) - .success() - .text("Successfully banned " + member.getAsMention() + " for `" + reason + "`!") - ); - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CheckWarnsCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CheckWarnsCommand.java deleted file mode 100644 index e2add7d6..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CheckWarnsCommand.java +++ /dev/null @@ -1,75 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.mysql.storage.Warning; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.*; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.Objects; -import java.util.Set; - -public class CheckWarnsCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - public CheckWarnsCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "checkwarns"; - } - - @Override - public String getDescription() { - return "Check the warnings of a user."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.USER, "user", "Select user.", true), - }; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - User user = Objects.requireNonNull(e.getOption("user")).getAsUser(); - - Set warnings = TechDiscordBot.getStorage().retrieveWarningsByUserID(user.getId()); - - TechEmbedBuilder embed = new TechEmbedBuilder("User Warned"); - - embed.text("This user has "+warnings.size()+" warnings."); - - for (Warning warning : warnings) { - embed.addField(warning.getTimeFormatted(), "Reason: "+warning.getReason()+" | ID: "+warning.getId()+"\nIssuer: "+warning.getReporter().getAsMention(), false); - } - - e.replyEmbeds(embed.build()).queue(); - } -} - diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CodeCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CodeCommand.java deleted file mode 100644 index d64d6c04..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/CodeCommand.java +++ /dev/null @@ -1,54 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.UUID; - -public class CodeCommand extends CommandModule { - - public CodeCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "code"; - } - - @Override - public String getDescription() { - return "Get a random code for verification"; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 2; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - String code = UUID.randomUUID().toString().split("-")[0]; - - e.replyEmbeds(new TechEmbedBuilder("Manual Verification Code") - .text("```TechManualVerification."+code+"```") - .build()).queue(); - } - -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/DeleteWarnCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/DeleteWarnCommand.java deleted file mode 100644 index 6320b304..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/DeleteWarnCommand.java +++ /dev/null @@ -1,80 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.mysql.storage.Warning; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.MessageEmbed; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.Objects; - -public class DeleteWarnCommand extends CommandModule { - - private final DefinedQuery ADMIN_ROLES = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Senior Supporter", "Assistant", "Developer", "\uD83D\uDCBB Coding Wizard"); - } - }; - - public DeleteWarnCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "delwarn"; - } - - @Override - public String getDescription() { - return "Delete a warning."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return ADMIN_ROLES.query().stream().map(CommandPrivilege::enable).toArray(CommandPrivilege[]::new); - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.STRING, "id", "Warning id.", true), - }; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - String id = Objects.requireNonNull(e.getOption("id")).getAsString(); - - Warning warning = TechDiscordBot.getStorage().retrieveWarningById(id); - if(warning != null){ - MessageEmbed msg = new TechEmbedBuilder("Warning Deleted") - .text("Warning for "+warning.getMember().getAsMention()+" with id "+warning.getId()+" has been successfully deleted.") - .build(); - e.replyEmbeds(msg).queue(); - - warning.delete(); - }else{ - MessageEmbed msg = new TechEmbedBuilder("Warning Not Found") - .text("Warning with id "+id+" not found.") - .build(); - e.replyEmbeds(msg).queue(); - } - } -} - diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/FeedbackCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/FeedbackCommand.java deleted file mode 100644 index 054dadaf..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/FeedbackCommand.java +++ /dev/null @@ -1,49 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class FeedbackCommand extends CommandModule { - - public FeedbackCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { return "feedback"; } - - @Override - public String getDescription() { - return "Returns the feedback website!"; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.replyEmbeds(new TechEmbedBuilder("Feedback") - .success() - .text("For suggestions, <#1020188847461629972>.\n" + "For Bug Reports, <#1020188935953076244>.\n" + "For Enhancements, <#1020189010406150204>.") - .build() - ).queue(); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GetReleaseCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GetReleaseCommand.java deleted file mode 100644 index cf7dc1d7..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GetReleaseCommand.java +++ /dev/null @@ -1,109 +0,0 @@ -//package me.TechsCode.TechDiscordBot.module.cmds; -// -//import me.TechsCode.TechDiscordBot.TechDiscordBot; -//import me.TechsCode.TechDiscordBot.github.GitHubUtil; -//import me.TechsCode.TechDiscordBot.github.GithubRelease; -//import me.TechsCode.TechDiscordBot.module.CommandModule; -//import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -//import me.TechsCode.TechDiscordBot.objects.Query; -//import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -//import net.dv8tion.jda.api.entities.Category; -//import net.dv8tion.jda.api.entities.Member; -//import net.dv8tion.jda.api.entities.Role; -//import net.dv8tion.jda.api.entities.TextChannel; -//import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -//import net.dv8tion.jda.api.interactions.commands.Command; -//import net.dv8tion.jda.api.interactions.commands.OptionType; -//import net.dv8tion.jda.api.interactions.commands.build.OptionData; -//import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; -// -//import java.util.stream.Collectors; -// -//public class GetReleaseCommand extends CommandModule { -// -// private final DefinedQuery SUPPORT_ROLES = new DefinedQuery() { -// @Override -// protected Query newQuery() { return bot.getRoles("Supporter", "Senior Supporter", "Assistant", "Developer", "\uD83D\uDCBB Coding Wizard"); } -// }; -// -// private final DefinedQuery SUPPORT_CATEGORIES = new DefinedQuery() { -// @Override -// protected Query newQuery() { return bot.getCategories("🎫 ︱Tickets", "📦︱Paid Plugin Support", "📦︱Free Plugin Support", "staff discussions"); } -// }; -// -// public GetReleaseCommand(TechDiscordBot bot) { -// super(bot); -// } -// -// @Override -// public String getName() { -// return "release"; -// } -// -// @Override -// public String getDescription() { -// return "Get a plugin's latest GitHub jar file."; -// } -// -// @Override -// public CommandPrivilege[] getCommandPrivileges() { -// return SUPPORT_ROLES.query().stream().map(CommandPrivilege::enable).toArray(CommandPrivilege[]::new); -// } -// -// @Override -// public OptionData[] getOptions() { -// if(TechDiscordBot.getSpigotStatus().isUsable()){ -// return new OptionData[] { -// new OptionData(OptionType.STRING, "plugin", "The plugin name.", true) -// .addChoices(TechDiscordBot.getSpigotAPI().getSpigotResources().stream().map(r -> new Command.Choice(r.getName().replace(" ", ""), r.getName().replace(" ", ""))).collect(Collectors.toList())) -// }; -// }else{ -// return new OptionData[] { -// new OptionData(OptionType.STRING, "plugin", "The plugin name.", true) -// .addChoice("Error getting plugins", "error") -// }; -// } -// } -// -// @Override -// public int getCooldown() { -// return 4; -// } -// -// @Override -// public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { -// String plugin = e.getOption("plugin").getAsString(); -// if(plugin.equals("error")) -// return; -// -// if (SUPPORT_CATEGORIES.query().stream().anyMatch(c -> c.getId().equals(channel.getParent().getId()))) { -// e.reply("Getting release... please wait.").queue(q -> { -// GithubRelease release = GitHubUtil.getLatestRelease(plugin); -// -// if (release == null) { -// q.editOriginal("**Failed!** Could not get the release!\n\n**Possible reasons:**\n- The repo isn't valid.\n- There is no release in the repo.\n- Github is down.").queue(); -// } else if (release.getFile() != null) { -// q.editOriginal(release.getFile(), plugin + ".jar") -// .queue(msg2 -> release.getFile().delete()); -// q.editOriginalEmbeds( -// new TechEmbedBuilder(release.getRelease().getName()) -// .text("```" + (release.getRelease().getBody().isEmpty() ? "No changes specified." : release.getRelease().getBody().replaceAll(" \\|\\| ", "\n")) + "```") -// .build() -// ).queue(); -// } else { -// q.editOriginal("**Failed!** Could not get the file!\n\n**Possible reasons:**\n- The developer messed up.\n- The release has no files for some reason.\n- GitHub is down.").queue(); -// } -// }); -// } else { -// StringBuilder channels = new StringBuilder(); -// SUPPORT_CATEGORIES.query().forEach(c -> channels.append("\n - ").append(c.getAsMention())); -// -// e.replyEmbeds( -// new TechEmbedBuilder("Get Release - Error") -// .text("You can not use this command in this channel's category.\n\n**Available Categories:**" + channels) -// .error() -// .build() -// ).setEphemeral(true).queue(); -// } -// } -//} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GuidesCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GuidesCommand.java deleted file mode 100644 index 9bb3d3b2..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/GuidesCommand.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class GuidesCommand extends CommandModule { - - public GuidesCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { return "guides"; } - - @Override - public String getDescription() { - return "Get other websites related to techscode."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://guides.ultracustomizer.com/").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/HowtoCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/HowtoCommand.java deleted file mode 100644 index 5eeaadcc..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/HowtoCommand.java +++ /dev/null @@ -1,81 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class HowtoCommand extends CommandModule { - - public HowtoCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "howto"; - } - - @Override - public String getDescription() { - return "Howto about popular topics."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.STRING, "topic", "Select Topic.", true) - .addChoice("Hex & Gradient", "Hex & Gradient"), - - }; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - String topic = e.getOption("topic").getAsString(); - - if(topic.equalsIgnoreCase("Hex & Gradient")) { - e.replyEmbeds( - new TechEmbedBuilder("How To Use Hex & Gradient") - .success() - .text("In order to use **Hex** and **Gradients** in Ultra and Insane plugins," + - "you will have to use two different formats.\n" + - "\n" + - "__For Hex Colors__ >\n" + - "```\n" + - "{#RRGGBB}Some Text```\n" + - "__For Gradients Colors__ >\n" + - "```{#RRGGBB>}Some Text{#RRGGBB<}```\n" + - "To be able to create gradient colors in an easier way and having a preview of them you can use this [site](https://rgb.fedee.tk/), you have to select as `Type` **TechsCode {#rrggbb>}** then write the text you want to use in `Message`, after modify the colors and finally copy the text where it will be written `Output`.") - //.field("EXAMPLE FIELD", "EXAMPLE FIELD CONTENT", true) - .build() - ).queue(); - } - } -} -// Example -// if(topic.equalsIgnoreCase("Test")) { -// e.replyEmbeds( -// new TechEmbedBuilder("EXAMPLE TITLE") -// .success() -// .text("EXAMPLE TEXT") -// .field("EXAMPLE FIELD", "EXAMPLE FIELD CONTENT", true) -// .build() -// ).queue(); -// } - diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/InsaneEditorCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/InsaneEditorCommand.java deleted file mode 100644 index 6d887743..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/InsaneEditorCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -//package me.TechsCode.TechDiscordBot.module.cmds; -// -//import me.TechsCode.TechDiscordBot.TechDiscordBot; -//import me.TechsCode.TechDiscordBot.module.CommandModule; -//import net.dv8tion.jda.api.entities.Member; -//import net.dv8tion.jda.api.entities.TextChannel; -//import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -//import net.dv8tion.jda.api.interactions.commands.build.OptionData; -//import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; -// -//public class InsaneEditorCommand extends CommandModule { -// -// public InsaneEditorCommand(TechDiscordBot bot) { -// super(bot); -// } -// -// @Override -// public String getName() { -// return "insaneeditor"; -// } -// -// @Override -// public String getDescription() { -// return "Returns the Insane Editor website!"; -// } -// -// @Override -// public CommandPrivilege[] getCommandPrivileges() { -// return new CommandPrivilege[0]; -// } -// -// @Override -// public OptionData[] getOptions() { -// return new OptionData[0]; -// } -// -// @Override -// public int getCooldown() { -// return 5; -// } -// -// @Override -// public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { -// e.reply("https://insaneeditor.com").queue(); -// } -//} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/KickCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/KickCommand.java deleted file mode 100644 index c8153daa..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/KickCommand.java +++ /dev/null @@ -1,85 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class KickCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getRoles("Staff"); } - }; - - public KickCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "kick"; - } - - @Override - public String getDescription() { - return "Kick a member from this guild."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.USER, "member", "The member to kick.", true), - new OptionData(OptionType.STRING, "reason", "The reason to kick the member.", false) - }; - } - - @Override - public int getCooldown() { - return 4; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - Member member = e.getOption("member").getAsMember(); - String reason = e.getOption("reason").getAsString(); - - if (member.getRoles().contains(STAFF_ROLE.query().first())) { - e.replyEmbeds( - new TechEmbedBuilder("Kick - Error") - .error() - .text("You cannot kick this user") - .build() - ).queue(); - } else if (member == e.getMember()) { - e.replyEmbeds( - new TechEmbedBuilder("Kick - Error") - .error() - .text("You cannot kick yourself") - .build() - ).queue(); - } else { - member.kick(reason).queue(); - - e.replyEmbeds( - new TechEmbedBuilder("Kicked " + member.getUser().getName() + "#" + member.getUser().getDiscriminator()) - .success() - .text("Successfully kicked " + member.getAsMention() + (reason == null ? "!" : " for `" + reason + "`!")) - .build() - ).queue(); - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MCMarketCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MCMarketCommand.java deleted file mode 100644 index 43404b6e..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MCMarketCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class MCMarketCommand extends CommandModule { - - public MCMarketCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "mc-market"; - } - - @Override - public String getDescription() { - return "Returns MC-Market's website."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 10; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://mc-market.org/").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MuteCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MuteCommand.java deleted file mode 100644 index b9ecd546..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/MuteCommand.java +++ /dev/null @@ -1,97 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.logs.PunishLogs; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class MuteCommand extends CommandModule { - - private final DefinedQuery MUTED_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Muted"); - } - }; - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - public MuteCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "mute"; - } - - @Override - public String getDescription() { - return "Mute/unmute a member from this guild."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.USER, "member", "The member to mute.", true) - }; - } - - @Override - public int getCooldown() { - return 2; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - Member member = e.getOption("member").getAsMember(); - - if (member.getRoles().contains(STAFF_ROLE.query().first())) { - e.replyEmbeds( - new TechEmbedBuilder("Mute - Error") - .error() - .text("You cannot mute this user") - .build() - ).queue(); - - } else if (member == e.getMember()) { - e.replyEmbeds( - new TechEmbedBuilder("Mute - Error") - .error() - .text("You cannot mute yourself") - .build() - ).queue(); - - } else if(memberHasMutedRole(member)) { - e.getGuild().removeRoleFromMember(member, MUTED_ROLE.query().first()).queue(); - e.reply(member.getAsMention() + " is no longer muted!").queue(); - PunishLogs.log(member.getAsMention() + " is no longer muted!"); - } else { - e.getGuild().addRoleToMember(member, MUTED_ROLE.query().first()).queue(); - e.reply(member.getAsMention() + " is now muted!").queue(); - PunishLogs.log(member.getAsMention() + " is now muted!"); - } - } - - public boolean memberHasMutedRole(Member member) { - return member.getRoles().contains(MUTED_ROLE.query().first()); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/OverviewCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/OverviewCommand.java deleted file mode 100644 index 9bfbfe15..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/OverviewCommand.java +++ /dev/null @@ -1,136 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.Plugin; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.awt.*; -import java.util.Arrays; - -public class OverviewCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getRoles("Staff"); } - }; - private final DefinedQuery OVERVIEW_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getChannels("\uD83D\uDCCC︱overview"); } - }; - - public OverviewCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "overview"; - } - - @Override - public String getDescription() { - return "Resend the #overview messages."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 10; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - if(!TechDiscordBot.getSpigotStatus().isUsable()) { - e.replyEmbeds( - new TechEmbedBuilder("API") - .text("The API has to be usable to execute this command!") - .error() - .build() - ).setEphemeral(true).queue(); - return; - } - - e.reply("Sending messages...").queue(); - - showAll(); - } - - public void showAll() { - showInfo(); - showFeedback(); - showPlugins(); - showPatreon(); - showInvite(); - } - -// @SubscribeEvent -// public void onReactAdd(GuildMessageReactionAddEvent e) { -// if(e.getChannel() != OVERVIEW_CHANNEL.query().first() || e.getUser().isBot()) -// return; -// -// Emote emote = bot.getEmotes("TechSupport").first(); -// -// if(e.getReaction().getReactionEmote().isEmote() && e.getReaction().getReactionEmote().getEmote() == emote) { -// if(e.getMember().getRoles().stream().anyMatch(r -> r.getName().equals("Member"))) -// return; -// -// e.getGuild().addRoleToMember(e.getMember(), bot.getRoles("Member").first()).queue(); -// } -// } - - public void showInfo() { - new TechEmbedBuilder("Tech's Plugin Support") - .text("Welcome to **Tech's Plugin Support**. Here, not only can you get support for Tech's Plugins. You can talk and socialize with people too! You can also get help with other plugins!\n\nIf you're new here and need help with one or more of Tech's Plugins, you can verify in <#907349490556616745> to get support. Once you do, you will get access to the specified support channels.") - .thumbnail("https://i.imgur.com/SfFEnoU.png") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showFeedback() { - new TechEmbedBuilder("Feedback") - .text("Would you like to suggest a feature or report a bug for Tech's Plugins? You can do so by clicking here: https://github.com/TechsCode-Team/Feedback/discussions") - .thumbnail("https://i.imgur.com/nzfiUTy.png") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showInvite() { - new TechEmbedBuilder() - .text("**Oh, look!** There is an invite: https://discord.gg/3JuHDm8") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showPlugins() { - Arrays.stream(Plugin.values()).forEach(plugin -> new TechEmbedBuilder(plugin.getRoleName()) - .text((plugin.getDescription().replace(" (", ". (") + (plugin.getDescription().endsWith(".") || plugin.getDescription().endsWith(")") ? "" : "."))) - .field("Download Links", plugin.getPluginMarketplace().toString(), true) - .field("Wiki", plugin.getWiki(), true) - .color(plugin.getColor()) - .thumbnail(plugin.getResourceLogo()) - .queue(OVERVIEW_CHANNEL.query().first())); - } - - public void showPatreon() { - new TechEmbedBuilder("TechsCode Patreon") - .text("Join our Patreon **program today** and get __exclusive__ and great rewards! \n\n http://patreon.techscode.com") - .color(Color.decode("#f96854")) - .thumbnail("https://techscode.com/patreon.gif") - .queue(OVERVIEW_CHANNEL.query().first()); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PastebinCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PastebinCommand.java deleted file mode 100644 index 9577609a..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PastebinCommand.java +++ /dev/null @@ -1,44 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class PastebinCommand extends CommandModule { - - public PastebinCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { return "pastebin"; } - - @Override - public String getDescription() { - return "Returns the pastebin website!"; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://paste.techscode.com/").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PatreonCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PatreonCommand.java deleted file mode 100644 index 8c7b33cb..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PatreonCommand.java +++ /dev/null @@ -1,48 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class PatreonCommand extends CommandModule { - - public PatreonCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "patreon"; - } - - @Override - public String getDescription() { - return "Returns the patreon website!"; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - boolean isPatron = m.getRoles().stream().anyMatch(r -> r.getName().equals("Patreon")); - - e.reply((isPatron ? "Thank you for being a Patron!\n\n" : "") + "https://patreon.com/TechsCode").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PluginCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PluginCommand.java deleted file mode 100644 index 5efa2165..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PluginCommand.java +++ /dev/null @@ -1,59 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.Objects; - -public class PluginCommand extends CommandModule { - - public PluginCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "plugin"; - } - - @Override - public String getDescription() { return "Get info/links about a plugin."; } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.STRING, "plugin", "Select Plugin", true) - .addChoice("Vault", "Vault") - .addChoice("PlaceholderAPI", "PlaceholderAPI") - .addChoice("ProtocolLib", "ProtocolLib") - .addChoice("TAB", "TAB") - .addChoice("NametagEdit", "NametagEdit"), - - }; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - String topic = Objects.requireNonNull(e.getOption("plugin")).getAsString(); - - if (topic.equalsIgnoreCase("Vault")) { e.reply("https://www.spigotmc.org/resources/vault.34315/").queue(); } - if (topic.equalsIgnoreCase("PlaceholderAPI")) { e.reply("https://www.spigotmc.org/resources/placeholderapi.6245/").queue(); } - if (topic.equalsIgnoreCase("ProtocolLib")) { e.reply("https://www.spigotmc.org/resources/protocollib.1997/").queue(); } - if (topic.equalsIgnoreCase("TAB")) { e.reply("https://github.com/NEZNAMY/TAB").queue(); } - if (topic.equalsIgnoreCase("NametagEdit")) { e.reply("https://github.com/NEZNAMY/TAB").queue(); }}} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PolymartCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PolymartCommand.java deleted file mode 100644 index 3fdb9b0e..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PolymartCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class PolymartCommand extends CommandModule { - - public PolymartCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "polymart"; - } - - @Override - public String getDescription() { - return "Returns Polymart's website."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 10; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://polymart.org/").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PreorderCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PreorderCommand.java deleted file mode 100644 index 32c9016e..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PreorderCommand.java +++ /dev/null @@ -1,140 +0,0 @@ -//package me.TechsCode.TechDiscordBot.module.cmds; -// -//import me.TechsCode.TechDiscordBot.TechDiscordBot; -//import me.TechsCode.TechDiscordBot.module.CommandModule; -//import me.TechsCode.TechDiscordBot.mysql.storage.Preorder; -//import me.TechsCode.TechDiscordBot.objects.Query; -//import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -//import net.dv8tion.jda.api.entities.Emote; -//import net.dv8tion.jda.api.entities.Member; -//import net.dv8tion.jda.api.entities.Role; -//import net.dv8tion.jda.api.entities.TextChannel; -//import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -//import net.dv8tion.jda.api.interactions.commands.OptionType; -//import net.dv8tion.jda.api.interactions.commands.build.OptionData; -//import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; -// -//import java.util.List; -//import java.util.stream.Collectors; -//import java.util.stream.IntStream; -// -//public class PreorderCommand extends CommandModule { -// -// public PreorderCommand(TechDiscordBot bot) { -// super(bot); -// } -// -// @Override -// public String getName() { -// return "preorder"; -// } -// -// @Override -// public String getDescription() { -// return "Show a member's preorder."; -// } -// -// @Override -// public CommandPrivilege[] getCommandPrivileges() { -// return new CommandPrivilege[0]; -// } -// -// @Override -// public OptionData[] getOptions() { -// return new OptionData[] { -// new OptionData(OptionType.USER, "member", "View this member's preorder. (Default: You)"), -// new OptionData(OptionType.BOOLEAN, "show-email", "Show the member's email? (Default: False)"), -// new OptionData(OptionType.BOOLEAN, "show-transaction-id", "Show the transaction id? (Default: False)") -// }; -// } -// -// @Override -// public int getCooldown() { -// return 3; -// } -// -// @Override -// public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { -// boolean preOrdersExist = getRoles().size() > 0; -// -// if(!preOrdersExist) { -// e.replyEmbeds( -// new TechEmbedBuilder("Preorder Command - Error") -// .error() -// .text("Looks like there are currently no pre orders!") -// .build() -// ).setEphemeral(true).queue(); -// return; -// } -// -// Member member = e.getOption("member") == null ? null : e.getOption("member").getAsMember(); -// if(member == null) member = m; -// -// Member finalSelectedMember = member; -// Preorder preorder = TechDiscordBot.getStorage().getPreorders(getRoles().get(0).replace(" Preorder", ""), false).stream().filter(po -> po.getDiscordId() == finalSelectedMember.getUser().getIdLong()).findFirst().orElse(null); -// -// if(preorder == null) { -// e.replyEmbeds( -// new TechEmbedBuilder("Preorder Command - Error") -// .error() -// .text("Could not find a preorder that belongs to " + member.getAsMention() + "!") -// .build() -// ).setEphemeral(true).queue(); -// return; -// } -// -// boolean showEmail = (e.getOption("show-email") != null && e.getOption("show-email").getAsBoolean()) && (preorder.getDiscordId() == member.getUser().getIdLong() || isStaff(member)); -// boolean showTransactionId = (e.getOption("show-transaction-id") != null && e.getOption("show-transaction-id").getAsBoolean()) && (preorder.getDiscordId() == member.getUser().getIdLong() || isStaff(member)); -// -// Query query = bot.getEmotes(preorder.getPlugin().replace(" ", "")); -// -// e.replyEmbeds( -// new TechEmbedBuilder("Preorder - " + member.getEffectiveName() + "#" + member.getUser().getDiscriminator()) -// .success() -// .field("Email", (showEmail ? preorder.getEmail() : obfuscateEmail(preorder.getEmail())), true) -// .field("Transaction ID", (showTransactionId ? preorder.getTransactionId() : obfuscateTransactionId(preorder.getTransactionId())), true) -// .field("Plugin", (query.hasAny() ? query.first().getAsMention() + " " : "") + preorder.getPlugin(), true) -// .field("Discord Name", preorder.getDiscordName() + " (" + member.getAsMention() + ")", true) -// .build() -// ).queue(); -// } -// -// public String obfuscateEmail(String email) { -// if(email.equals("notAvailable") || email.equals("ManuallyAdded")) -// return "Unknown"; -// -// int index = email.indexOf("@"); -// if(index == -1) -// return email; -// -// StringBuilder length = new StringBuilder(); -// for(int i = 0; i < index; i++) -// length.append("\\*"); -// -// StringBuilder sb = new StringBuilder(email); -// sb.replace(0, index, length.toString()); -// -// return sb.toString(); -// } -// -// public String obfuscateTransactionId(String transactionId) { -// if(transactionId.equals("NONE") || transactionId.equals("something")) -// return "Unknown"; -// -// StringBuilder sb = new StringBuilder(transactionId); -// -// String length = IntStream.range(0, (int) (transactionId.length() / 1.5d)).mapToObj(i -> "\\*").collect(Collectors.joining()); -// -// sb.replace(0, (int)(transactionId.length() / 1.5d), length); -// -// return sb.toString(); -// } -// -// public List getRoles() { -// return TechDiscordBot.getJDA().getRoles().stream().map(Role::getName).filter(name -> name.endsWith(" Preorder")).collect(Collectors.toList()); -// } -// -// public boolean isStaff(Member member) { -// return member.getRoles().stream().anyMatch(role -> role.getName().equals("Staff")); -// } -//} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PruneCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PruneCommand.java deleted file mode 100644 index ae78b9c6..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/PruneCommand.java +++ /dev/null @@ -1,96 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.MessageChannel; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; -import net.dv8tion.jda.api.interactions.commands.OptionMapping; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; -import net.dv8tion.jda.api.interactions.components.Button; - -public class PruneCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getRoles("Staff"); } - }; - - public PruneCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "prune"; - } - - @Override - public String getDescription() { - return "Prune messages from this channel."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.INTEGER, "amount", "The amount of messages to prune. (Default 100)") - }; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - String userId = e.getUser().getId(); - OptionMapping amountOption = e.getOption("amount"); - - int amount = amountOption == null ? 100 : (int) Math.min(200, Math.max(2, amountOption.getAsLong())); - - e.reply("**This will delete " + amount + " messages.**\nAre you sure?") - .addActionRow( - Button.success(userId + ":prune:" + amount, "Yes!"), - Button.danger(userId + ":delete", "Nevermind!") - ).queue(); - } - - @SubscribeEvent - public void onButtonClick(ButtonClickEvent event) { - String[] id = event.getComponentId().split(":"); - - String authorId = id[0]; - String type = id[1]; - - if (!authorId.equals(event.getUser().getId())) - return; - - MessageChannel channel = event.getChannel(); - event.deferEdit().queue(); - - switch (type) { - case "prune": - int amount = Integer.parseInt(id[2]); - event.getChannel().getIterableHistory() - .skipTo(event.getMessageIdLong()) - .takeAsync(amount) - .thenAccept(channel::purgeMessages); - case "delete": - event.getHook().deleteOriginal().queue(); - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RemindMeCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RemindMeCommand.java deleted file mode 100644 index aa716426..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RemindMeCommand.java +++ /dev/null @@ -1,86 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.reminders.Reminder; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.text.SimpleDateFormat; -import java.util.Date; - -public class RemindMeCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - public RemindMeCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "remind"; - } - - @Override - public String getDescription() { - return "Set a reminder to remind yourself."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.STRING, "time", "How long FROM NOW to be reminded.", true), - new OptionData(OptionType.STRING, "reminder", "What to be reminded about.", true), - }; - } - - @Override - public int getCooldown() { - return 3; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - String time = e.getOption("time").getAsString(); - String reminder = e.getOption("reminder").getAsString(); - - Reminder r = TechDiscordBot.getRemindersManager().createReminder(e.getUser(), time, reminder, channel); - - if(r == null) { - e.replyEmbeds( - new TechEmbedBuilder("Reminder - Error") - .text("An error has occurred. Did you specify a time and a reason?\n\n**Here are some examples!**:\n`/remind 1 day Fix x thing.`\n`/remind 30 hours I need help.`\n`/remind 30 hours I need help. dm` (makes it a dm)") - .error() - .build() - ).queue(); - } else { - SimpleDateFormat sdf = new SimpleDateFormat("MMMM d, yyyy 'at' hh:mm:ss a"); - - e.replyEmbeds( - new TechEmbedBuilder("Reminder Set!") - .text("I will remind you for **" + r.getReminder() + "**!") - .success() - .build() - ).queue(); - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RoleCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RoleCommand.java deleted file mode 100644 index a68dbcef..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RoleCommand.java +++ /dev/null @@ -1,140 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.logs.RoleLogs; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.awt.*; -import java.util.ArrayList; - -public class RoleCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLES = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Senior Supporter"); - } - }; - - private final ArrayList SENIOR_SUPPORTER_ROLES = new ArrayList() {{ - add("Ultra Permissions"); - add("Ultra Customizer"); - add("Ultra Punishments"); - add("Ultra Regions"); - add("Insane Shops"); - add("Ultra Economy"); - add("Ultra Scoreboards"); - add("Ultra Motd"); - add("Keep Roles"); - add("Spigot"); - add("MC-Market"); - add("Songoda"); - add("Polymart"); - add("Verified"); - add("Review Squad"); - }}; - - public RoleCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "role"; - } - - @Override - public String getDescription() { - return "Give a member a specific role."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return STAFF_ROLES.query().stream().map(CommandPrivilege::enable).toArray(CommandPrivilege[]::new); - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.USER, "member", "The member to give a new role", true), - new OptionData(OptionType.ROLE, "role", "The role which will be given to the member", true) - }; - } - - @Override - public int getCooldown() { - return 0; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - Member member = e.getOption("member").getAsMember(); - Role role = e.getOption("role").getAsRole(); - - if(!m.getRoles().contains(TechDiscordBot.getGuild().getRoleById(854044253885956136L)) && !m.getRoles().contains(TechDiscordBot.getGuild().getRoleById(608113993038561325L)) && !m.getRoles().contains(TechDiscordBot.getGuild().getRoleById(311178859171282944L))) { - e.replyEmbeds( - new TechEmbedBuilder("Role Management") - .color(Color.orange) - .text("**Senior Supporter**: Verified, Plugins, Marketplaces, Review Squad & Keep Roles\n**Assistant**: Staff, Supporter Roles, Retired, Wiki Editor & Plugin Lab\n**Developer**: Assistant & Team Manager") - .build() - ).queue(); - return; - } - - if((m.getRoles().contains(TechDiscordBot.getGuild().getRoleById(854044253885956136L)) && !m.getRoles().contains(TechDiscordBot.getGuild().getRoleById(608113993038561325L)) && !SENIOR_SUPPORTER_ROLES.contains(role.getName()))) { - e.replyEmbeds( - new TechEmbedBuilder("Role Management") - .color(Color.orange) - .text("**Senior Supporter**: Verified, Plugins, Marketplaces, Review Squad & Keep Roles") - .build() - ).queue(); - return; - } - - if(m.equals(member)) { - e.replyEmbeds( - new TechEmbedBuilder("Role Management - Error") - .error() - .text("You can't edit your own roles!") - .build() - ).queue(); - return; - } - - if(member.getRoles().contains(role)) { - TechDiscordBot.getGuild().removeRoleFromMember(member, role).complete(); - e.replyEmbeds( - new TechEmbedBuilder("Role Removed") - .error().text("Removed " + role.getAsMention() + " from " + member.getAsMention()) - .build() - ).queue(); - - RoleLogs.log( - new TechEmbedBuilder("Role Removed") - .error().text("Removed " + role.getAsMention() + " from " + member.getAsMention()) - ); - } else { - TechDiscordBot.getGuild().addRoleToMember(member, role).complete(); - e.replyEmbeds( - new TechEmbedBuilder("Role Added") - .success().text("Added " + role.getAsMention() + " to " + member.getAsMention()) - .build() - ).queue(); - - RoleLogs.log( - new TechEmbedBuilder("Role Added") - .success().text("Added " + role.getAsMention() + " to " + member.getAsMention()) - ); - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RulesCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RulesCommand.java deleted file mode 100644 index 975149be..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/RulesCommand.java +++ /dev/null @@ -1,210 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.ArrayList; -import java.util.List; - -public class RulesCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - private final DefinedQuery OVERVIEW_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getChannels("\uD83D\uDCCC︱overview"); - } - }; - - public RulesCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "rules"; - } - - @Override - public String getDescription() { - return "Resend the #overview rules messages."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 10; - } - - @Override - public void onCommand(TextChannel channel, Member member, SlashCommandEvent e) { - e.reply("Sending messages...").queue(); - OVERVIEW_CHANNEL.query().first().getIterableHistory() - .takeAsync(200) - .thenAccept(channel::purgeMessages); - - showAll(); - } - - public void showAll() { - showTOS(); - showRules_Section1(); - showRules_Section2(); - showRules_Section3(); - showNote(); - showRoles(); - } - - public void showTOS() { - new TechEmbedBuilder("Discord TOS & Guidelines") - .text("This server is compliant with the Discord Terms of Service and Guidelines. " + - "We will ban if the content is not a compliant. Be sure to familiarize yourself with them here:\n" + - "- [Terms of Service](https://dis.gd/tos)\n- [Content Guidelines](https://dis.gd/guidelines)" + - "\n\nOur Staff reserve the right to request a member to confirm their age if they are perceived to be potentially under 13. Noncompliance will result in the assumption of being under 13.") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showRules_Section1() { - new TechEmbedBuilder("Rules Section 1 - Text & Voice Chat") - .text("**`Article 1.1`**\n" + - "Attempting to bypass any blocked words or links may result in punishments.\n" + - "**`Article 1.2`**\n" + - "Hate speech is strictly prohibited.\n" + - "**`Article 1.3`**\n" + - "NSFW (Not safe for work) is strictly prohibited.\n" + - "**`Article 1.4`**\n" + - "Repeating a message five or more times will be classified as spam and prohibited.\n" + - "**`Article 1.5`**\n" + - "Disrespectful, malicious, and harmful messages are strictly prohibited.\n" + - "**`Article 1.6`**\n" + - "Mentioning a member then deleting your message is prohibited.\n" + - "**`Article 1.7`**\n" + - "Mass mentioning users is prohibited and will result in punishments.\n" + - "**`Article 1.8`**\n" + - "Providing any kind of support to any of Tech's plugins to unverified members is strictly prohibited.") - .thumbnail("https://i.imgur.com/SfFEnoU.png") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showRules_Section2() { - new TechEmbedBuilder("Rules Section 2 - Advertising") - .text("**`Article 2.1`**\n" + - "Advertising anywhere other than your about me and status is prohibited.\n" + - "**`Article 2.2`**\n" + - "DM Advertising is strictly prohibited and will result in heavy punishments. If a Tech's Plugin Support member directly messages you an advertisement, please create a ticket to report them.\n" + - "**`Article 2.3`**\n" + - "Advertising content such as scams, malware, or NSFW is strictly prohibited and will result in your account being banned.") - .thumbnail("https://i.imgur.com/SfFEnoU.png") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showRules_Section3() { - new TechEmbedBuilder("Rules Section 3 - Other") - .text("**`Article 3.1`**\n" + - "Inappropriate usernames and nicknames are prohibited.\n" + - "**`Article 3.2`**\n" + - "Using leaked or cracked copies of any resource are prohibited.\n" + - "**`Article 3.3`**\n" + - "Using or creating a modified version of premium resources is prohibited.\n" + - "**`Article 3.4`**\n" + - "Asking for the staff or other particular roles is prohibited.\n" + - "**`Article 3.5`**\n" + - "Promoting the use of leaked or cracked resources are strictly prohibited.\n" + - "**`Article 3.6`**\n" + - "Inviting or having alternative Discord accounts in this server may result in all of your accounts getting banned unless an Assistant or higher grants permission.\n" + - "**`Article 3.7`**\n" + - "Sharing another user's Personal Identifiable Information (\"PII\") without express permission from them is strictly prohibited.") - .thumbnail("https://i.imgur.com/SfFEnoU.png") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showNote() { - new TechEmbedBuilder() - .text("**PLEASE NOTE**: Staff do reserve the right to punish for things not listed on this list under the staff's discretion. Please use common sense, and if you are unsure about anything, please ask.") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public void showRoles() { - StringBuilder sBuilder = new StringBuilder(); - - int i = 0; - for(Role role : Role.values()) { - if(i != 0) - sBuilder.append("\n\n"); - - sBuilder.append(role.getAsMention()).append(": ").append(role.getDescription()); - - i++; - } - - new TechEmbedBuilder("Roles") - .text(sBuilder + "\n\nPlease don't ask to be Staff, it's annoying.") - .queue(OVERVIEW_CHANNEL.query().first()); - } - - public enum Role { - - CODING_WIZARD("Coding Wizard", "311178859171282944", "It was Tech & now it's MATRIX! The former head of the operations."), - DEVELOPER("Developer", "774690360836096062", "These are the Developers! They are in charge of helping the <@&311178859171282944> with the development of our plugins."), - ASSISTANT("Assistant", "608113993038561325", "This is the Developers Assistant! If the Developers are not online, he is in charge. Occasionally also helps with coding."), - STAFF("Staff", "608114002387533844", "They are here to help! Don't argue with Staff. If you think there is an issue, please contact <@&608113993038561325> or <@&311178859171282944>."), - PATREON("Patreon", "795101981051977788", "These are our incredible Patreon supporters who getting rewarded by us for their monthly support with various rewards, additions and exclusive stuff."), - DONATOR("Donator", "311179148691505152", "These are amazing people who have donated to Tech!"), - VERIFIED_CREATOR("Knows how to Code", "435183665719541761", "A role given to people who have well known coding projects."), - NITRO_BOOSTERS("Nitro Booster", "585559418008109075", "These are **AMAZING** people who are helping us to unlock great features for our Discord!"), - REVIEW_SQUAD("Review Squad", "457934035549683713", "These are the **AMAZING** people in the community who have review all of their plugin's owned by Tech."), - VERIFIED("Verified", "416174015141642240", "This role is given to members who have successfully verified that they've purchased *as least* one of Tech's resources."); - - private final String name; - private final String id; - private final String description; - - Role(String name, String id, String description) { - this.name = name; - this.id = id; - this.description = description; - } - - public String getName() { - return name; - } - - public String getId() { - return id; - } - - public String getAsMention() { - net.dv8tion.jda.api.entities.Role role = TechDiscordBot.getJDA().getRoleById(id); - - if(role == null) return getName(); - return role.getAsMention(); - } - - public String getDescription() { - return description; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SongodaCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SongodaCommand.java deleted file mode 100644 index 7679dcc7..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SongodaCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class SongodaCommand extends CommandModule { - - public SongodaCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "songoda"; - } - - @Override - public String getDescription() { - return "Returns Songoda's website."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 10; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://songoda.com/marketplace").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SpigotCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SpigotCommand.java deleted file mode 100644 index a56cdd43..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SpigotCommand.java +++ /dev/null @@ -1,46 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -public class SpigotCommand extends CommandModule { - - public SpigotCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "spigot"; - } - - @Override - public String getDescription() { - return "Returns SpigotMC's website."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[0]; - } - - @Override - public int getCooldown() { - return 10; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - e.reply("https://spigotmc.org").queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/StatusCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/StatusCommand.java deleted file mode 100644 index 67197796..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/StatusCommand.java +++ /dev/null @@ -1,127 +0,0 @@ -//package me.TechsCode.TechDiscordBot.module.cmds; -// -//import me.TechsCode.TechDiscordBot.TechDiscordBot; -//import me.TechsCode.TechDiscordBot.module.CommandModule; -//import me.TechsCode.TechDiscordBot.spigotmc.data.APIStatus; -//import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -//import net.dv8tion.jda.api.entities.Member; -//import net.dv8tion.jda.api.entities.TextChannel; -//import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -//import net.dv8tion.jda.api.interactions.commands.build.OptionData; -//import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; -// -//public class APICommand extends CommandModule { -// -// public APICommand(TechDiscordBot bot) { -// super(bot); -// } -// -// @Override -// public String getName() { -// return "status"; -// } -// -// @Override -// public String getDescription() { -// return "Fetches the API's status."; -// } -// -// @Override -// public CommandPrivilege[] getCommandPrivileges() { -// return new CommandPrivilege[0]; -// } -// -// @Override -// public OptionData[] getOptions() { -// return new OptionData[0]; -// } -// -// @Override -// public int getCooldown() { -// return 2; -// } -// -// @Override -// public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { -// APIStatus spigotStatus = bot.getSpigotStatus(); -// APIStatus marketStatus = bot.getMarketStatus(); -// APIStatus songodaStatus = bot.getSongodaStatus(); -// -// StringBuilder sb = new StringBuilder(); -// appendStatus("Spigot", spigotStatus, sb, m); -// appendStatus("MC-Market", marketStatus, sb, m); -// appendStatus("Songoda", songodaStatus, sb, m); -// -// e.replyEmbeds( -// new TechEmbedBuilder("API Status") -// .text(sb.toString()) -// .build() -// ).queue(); -// -// } -// -// private void appendStatus(String name, APIStatus status, StringBuilder sb, Member m) { -// if(!sb.toString().isEmpty()) -// sb.append("\n\n"); -// -// sb.append(status.getEmoji()).append(" **API Status - ").append(name).append("** (").append(status.getStatus()).append(")\n").append(status.getDescription()); -// sb.append("\n\n"); -// -// if(status.isUsable() && m.getRoles().stream().anyMatch(r -> r.getName().equals("Staff"))) { //Make sure the member is staff. -// if(name.equals("Spigot")) { -// int purchases = TechDiscordBot.getSpigotAPI().getSpigotPurchases().size(); -// int reviews = TechDiscordBot.getSpigotAPI().getSpigotReviews().size(); -// int updates = TechDiscordBot.getSpigotAPI().getSpigotUpdates().size(); -// int resources = TechDiscordBot.getSpigotAPI().getSpigotResources().size(); -// -// sb.append("**Purchases:** ").append(purchases).append("\n"); -// sb.append("**Reviews:** ").append(reviews).append("\n"); -// sb.append("**Updates:** ").append(updates).append("\n"); -// sb.append("**Resources:** ").append(resources).append("\n\n"); -// }else if(name.equals("MC-Market")) { -// int purchases = TechDiscordBot.getSpigotAPI().getMarketPurchases().size(); -// int reviews = TechDiscordBot.getSpigotAPI().getMarketReviews().size(); -// int updates = TechDiscordBot.getSpigotAPI().getMarketUpdates().size(); -// int resources = TechDiscordBot.getSpigotAPI().getMarketResources().size(); -// -// sb.append("**Purchases:** ").append(purchases).append("\n"); -// sb.append("**Reviews:** ").append(reviews).append("\n"); -// sb.append("**Updates:** ").append(updates).append("\n"); -// sb.append("**Resources:** ").append(resources).append("\n\n"); -// } else { -// sb.append("**Purchases:** ").append(TechDiscordBot.getSongodaAPI().getSpigotPurchases().size()).append("\n\n"); -// } -// } -// -// String lastUpdatedFormatted = "Never"; -// String botLastParsed = "Never"; -// -// switch (name) { -// case "Songoda": -// if (status.isUsable()) { -// lastUpdatedFormatted = ""; -// } -// -// sb.append("**Last Fetched**: ").append(lastUpdatedFormatted); -// break; -// case "Spigot": -// if (status.isUsable()) { -// lastUpdatedFormatted = ""; -// botLastParsed = ""; -// } -// -// sb.append("**Last Fetched**: ").append(lastUpdatedFormatted); -// sb.append("\n**Last Parsed**: ").append(botLastParsed); -// break; -// case "MC-Market": -// if (status.isUsable()) { -// lastUpdatedFormatted = ""; -// botLastParsed = ""; -// } -// -// sb.append("**Last Fetched**: ").append(lastUpdatedFormatted); -// sb.append("\n**Last Parsed**: ").append(botLastParsed); -// break; -// } -// } -//} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SubVerifyCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SubVerifyCommand.java deleted file mode 100644 index f373cd11..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/SubVerifyCommand.java +++ /dev/null @@ -1,215 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.logs.ServerLogs; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.awt.*; - -public class SubVerifyCommand extends CommandModule { - - private final DefinedQuery SUB_VERIFIED_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Sub Verified"); - } - }; - - private final DefinedQuery VERIFIED_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Verified"); - } - }; - - private final DefinedQuery STAFF_ROLES = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Senior Supporter", "Assistant", "Developer", "\uD83D\uDCBB Coding Wizard"); - } - }; - - private final DefinedQuery BOT_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Bot"); - } - }; - - public SubVerifyCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "subverify"; - } - - @Override - public String getDescription() { - return "Add a Sub Verification which will be linked to your account."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.STRING, "action", "Add or Remove a member as your sub verified user", true) - .addChoice("Add", "add") - .addChoice("Remove", "remove"), - new OptionData(OptionType.USER, "member", "The member to sub verify which is then linked with your verification", true) - }; - } - - @Override - public int getCooldown() { - return 0; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - String action = e.getOption("action").getAsString(); - Member member = e.getOption("member").getAsMember(); - - if(!action.equalsIgnoreCase("add") && !action.equalsIgnoreCase("remove")) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Usage") - .error() - .text("Please use '**add**' or '**remove**' as action argument \n **Usage:** /SubVerify ") - .build() - ).queue(); - return; - } - - if(!m.getRoles().contains(VERIFIED_ROLE.query().first())) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text("This command is only for **verified** user.") - .build() - ).queue(); - return; - } - - if(m.equals(member)) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text("You can't be your own sub verified user!") - .build() - ).queue(); - return; - } - - if(member.getRoles().contains(BOT_ROLE.query().first())) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text("You can't add a " + BOT_ROLE.query().first().getAsMention() + " as a " + SUB_VERIFIED_ROLE.query().first().getAsMention() + " user!") - .build() - ).queue(); - return; - } - - if(TechDiscordBot.getStorage().isSubVerifiedUser(member.getId()) && !TechDiscordBot.getStorage().getVerifiedIdFromSubVerifiedId(member.getId()).equals(m.getId())) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text("This user is already a " + SUB_VERIFIED_ROLE.query().first().getAsMention() + " user of " + TechDiscordBot.getGuild().getMemberById(TechDiscordBot.getStorage().getVerifiedIdFromSubVerifiedId(member.getId())).getAsMention()) - .build() - ).queue(); - return; - } - - if(action.equalsIgnoreCase("add")) { - if(TechDiscordBot.getStorage().hasSubVerification(m.getId())) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text("You need to remove your old sub verification first before you can add a new one.") - .build() - ).queue(); - return; - } if (member.getRoles().contains(SUB_VERIFIED_ROLE.query().first())) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text("You can not add a already verified user as your subverified user.") - .build() - ).queue(); - return; - } - - TechDiscordBot.getGuild().addRoleToMember(member, SUB_VERIFIED_ROLE.query().first()).queue(); - TechDiscordBot.getStorage().addSubVerification(m.getId(), member.getId()); - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Added") - .success() - .text("Successfully **added** " + member.getAsMention() + " as " + m.getAsMention() + "'s sub verified user") - .build() - ).queue(); - ServerLogs.log( - new TechEmbedBuilder("Subverification added") - .success() - .text("User: " + e.getMember().getAsMention() + " (" + e.getUser().getName() + "#" + e.getUser().getDiscriminator() + ", " + e.getUser().getId() + ") \n"+ - "has added: " + m.getAsMention() + "as a subverified user") - .thumbnail(e.getMember().getUser().getAvatarUrl()) - ); - return; - } - - if(action.equalsIgnoreCase("remove")) { - if(TechDiscordBot.getStorage().getSubVerifiedIdFromVerifiedId(m.getId()) == null) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text("You don't have an sub verified user!") - .build() - ).queue(); - return; - } - - if(TechDiscordBot.getStorage().getSubVerifiedIdFromVerifiedId(m.getId()) != null && !TechDiscordBot.getStorage().getSubVerifiedIdFromVerifiedId(m.getId()).equals(member.getId())) { - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Error") - .error() - .text(member.getAsMention() + " isn't your verified user!") - .build() - ).queue(); - return; - } - - TechDiscordBot.getGuild().removeRoleFromMember(member, SUB_VERIFIED_ROLE.query().first()).queue(); - TechDiscordBot.getStorage().removeSubVerification(m.getId()); - e.replyEmbeds( - new TechEmbedBuilder("Sub Verification - Removed") - .color(Color.orange) - .text("Successfully **removed** " + member.getAsMention() + " as " + m.getAsMention() + "'s sub verified user") - .build() - ).queue(); - ServerLogs.log( - new TechEmbedBuilder("Subverification Removed") - .error() - .text("User: " + e.getMember().getAsMention() + " (" + e.getUser().getName() + "#" + e.getUser().getDiscriminator() + ", " + e.getUser().getId() + ") \n"+ - "has added: " + m.getAsMention() + "as a subverified user") - .thumbnail(e.getMember().getUser().getAvatarUrl()) - ); - return; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/UserInfoCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/UserInfoCommand.java deleted file mode 100644 index aac68256..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/UserInfoCommand.java +++ /dev/null @@ -1,66 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.time.format.DateTimeFormatter; -import java.util.stream.Collectors; - -public class UserInfoCommand extends CommandModule { - - public UserInfoCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "info"; - } - - @Override - public String getDescription() { - return "Get information about a specific user."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.USER, "member", "Member to get info about. (Default: You)") - }; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - Member member = e.getOption("member") == null ? m : e.getOption("member").getAsMember(); - User user = member.getUser(); - - e.replyEmbeds(new TechEmbedBuilder(user.getName() + "#" + user.getDiscriminator()) - .field("Status", member.getOnlineStatus().getKey().substring(0, 1).toUpperCase() + member.getOnlineStatus().getKey().substring(1), true) - .field("Created At", user.getTimeCreated().format(DateTimeFormatter.RFC_1123_DATE_TIME), true) - .field("Joined At", member.getTimeJoined().format(DateTimeFormatter.RFC_1123_DATE_TIME), true) - .field("Flags", user.getFlags().clone().stream().map(User.UserFlag::getName).collect(Collectors.joining(", ")) + ".", false) - .field("Roles", member.getRoles().stream().map(Role::getAsMention).collect(Collectors.joining(", ")) + ".", false) - .thumbnail(user.getAvatarUrl()) - .build() - ).queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WarnCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WarnCommand.java deleted file mode 100644 index 0d3a651e..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WarnCommand.java +++ /dev/null @@ -1,100 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.mysql.storage.Warning; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.*; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.Objects; - -public class WarnCommand extends CommandModule { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - public WarnCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "warn"; - } - - @Override - public String getDescription() { - return "Warn a user."; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[] { CommandPrivilege.enable(STAFF_ROLE.query().first()) }; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.USER, "user", "Select a user.", true), - new OptionData(OptionType.STRING, "reason", "Enter a reason.", true) - .addChoice("Ghost Pinging", "Ghost Pinging") - .addChoice("Mass Mentioning", "Mass Mentioning") - .addChoice("Mini-Modding", "Mini-Modding") - .addChoice("Spamming", "Spamming") - .addChoice("NSFW Content", "NSFW Content") - .addChoice("Advertisement", "Advertisement") - .addChoice("Being Disrespectful", "Being Disrespectful") - .addChoice("Not Listening to Staff", "Not Listening to Staff") - .addChoice("Sending Bad Links", "Sending Bad Links") - .addChoice("Breaking Official Rules", "Breaking Official Rules") - .addChoice("Asking for Content/Plugins", "Asking for Content/Plugins") - .addChoice("Racism/Discrimination", "Racism/Discrimination"), - }; - } - - @Override - public int getCooldown() { - return 5; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - User user = Objects.requireNonNull(e.getOption("user")).getAsUser(); - Member member = TechDiscordBot.getGuild().getMemberById(user.getId()); - - String reason = Objects.requireNonNull(e.getOption("reason")).getAsString(); - - MessageEmbed msg; - - assert member != null; - if(member.getRoles().contains(STAFF_ROLE.query().first())){ - msg = new TechEmbedBuilder("User Warnings") - .text("You cannot warn a staff member.") - .build(); - e.replyEmbeds(msg).queue(); - return; - } - - Warning warning = new Warning(user.getId(), m.getId(), reason, System.currentTimeMillis()); - warning.save(); - - msg = new TechEmbedBuilder("User Warnings") - .addField("User:", warning.getMember().getAsMention(), false) - .addField("Reporter", warning.getReporter().getAsMention(), false) - .addField("Reason", warning.getReason(), false) - .build(); - e.replyEmbeds(msg).queue(); - - } -} - diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WikiCommand.java b/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WikiCommand.java deleted file mode 100644 index 913f2fcf..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/cmds/WikiCommand.java +++ /dev/null @@ -1,128 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.cmds; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.CommandModule; -import me.TechsCode.TechDiscordBot.util.Plugin; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.interactions.commands.OptionType; -import net.dv8tion.jda.api.interactions.commands.build.OptionData; -import net.dv8tion.jda.api.interactions.commands.privileges.CommandPrivilege; - -import java.util.List; -import java.util.stream.Collectors; - -public class WikiCommand extends CommandModule { - - public WikiCommand(TechDiscordBot bot) { - super(bot); - } - - @Override - public String getName() { - return "wiki"; - } - - @Override - public String getDescription() { - return "Returns the wiki website!"; - } - - @Override - public CommandPrivilege[] getCommandPrivileges() { - return new CommandPrivilege[0]; - } - - @Override - public OptionData[] getOptions() { - return new OptionData[] { - new OptionData(OptionType.BOOLEAN, "all", "Show all plugins"), - new OptionData(OptionType.BOOLEAN, "mine", "Show your plugins"), - }; - } - - @Override - public int getCooldown() { - return 2; - } - - @Override - public void onCommand(TextChannel channel, Member m, SlashCommandEvent e) { - boolean all = e.getOption("all") != null && e.getOption("all").getAsBoolean(); - boolean mine = e.getOption("mine") != null && e.getOption("mine").getAsBoolean(); - - if(Plugin.isPluginChannel(channel)) { - if(!all && !mine) { - showCurrentChannel(e, channel); - } else { - if(all) { - showAll(e); - } else if (mine) { - showYourPlugins(e, m); - } - } - } else { - if(!all && !mine) { - showYourPlugins(e, m); - } else if(all) { - showAll(e); - } - } - } - - public void showCurrentChannel(SlashCommandEvent e, TextChannel channel) { - if(Plugin.isPluginChannel(channel)) { - Plugin plugin = Plugin.byChannel(channel); - if(!plugin.hasWiki()) { - new TechEmbedBuilder("Wikis").error().text(plugin.getEmoji().getAsMention() + " " + plugin.getRoleName() + " unfortunately does not have a wiki!").sendTemporary(channel, 10); - return; - } - - e.replyEmbeds( - new TechEmbedBuilder("Wikis") - .text("*Showing the wiki of the support channel you're in.*\n\n" + plugin.getEmoji().getAsMention() + " " + plugin.getWiki()) - .build() - ).queue(); - } - } - - public void showYourPlugins(SlashCommandEvent e, Member member) { - boolean apiIsUsable = TechDiscordBot.getBot().getSpigotStatus().isUsable(); - - List plugins = Plugin.allWithWiki(); - if(apiIsUsable) plugins = Plugin.fromUser(member).stream().filter(Plugin::hasWiki).collect(Collectors.toList()); - - StringBuilder sb = new StringBuilder(); - if(!apiIsUsable) - sb.append(TechDiscordBot.getBot().getEmotes("offline").first().getAsMention()).append(" **The API is not online, showing all plugins with a wiki.**\n\n"); - if(apiIsUsable) - sb.append("*Showing all wikis of the plugins you own!*\n\n"); - if(plugins.isEmpty()) - sb.append("**You do not own of any of Tech's plugins, showing all wikis!**\n\n"); - if(plugins.isEmpty()) - plugins = Plugin.allWithWiki(); - plugins.forEach(p -> sb.append(p.getEmoji().getAsMention()).append(" ").append(p.getWiki()).append("\n")); - - e.replyEmbeds( - new TechEmbedBuilder("Wikis") - .text(sb.substring(0, sb.toString().length() - 1)) - .build() - ).queue(); - } - - public void showAll(SlashCommandEvent e) { - List plugins = Plugin.allWithWiki(); - StringBuilder sb = new StringBuilder(); - - sb.append("*Showing all wikis!*\n\n"); - plugins.forEach(p -> sb.append(p.getEmoji().getAsMention()).append(" ").append(p.getWiki()).append("\n")); - - e.replyEmbeds( - new TechEmbedBuilder("Wikis") - .text(sb.substring(0, sb.toString().length() - 1)) - .build() - ).queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ActivitiesModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ActivitiesModule.java deleted file mode 100644 index b959f4fd..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ActivitiesModule.java +++ /dev/null @@ -1,134 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.mysql.storage.Storage; -import me.TechsCode.TechDiscordBot.mysql.storage.Verification; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.spigotmc.data.Review; -import me.TechsCode.TechDiscordBot.spigotmc.data.Update; -import me.TechsCode.TechDiscordBot.util.Plugin; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; - -import java.util.Objects; -import java.util.concurrent.TimeUnit; - -public class ActivitiesModule extends Module { - - private final DefinedQuery UPDATES_ROLE = new DefinedQuery() { - protected Query newQuery() { - return bot.getRoles("Updates"); - } - }; - private final DefinedQuery ACTIVITIES_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getChannels("\uD83D\uDCDA︱activities"); - } - }; - - public ActivitiesModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() { - new Thread(() -> { - while (true) { - checkResources(); - - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(5)); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } - }).start(); - } - - @Override - public void onDisable() {} - - @Override - public String getName() { - return "Activities Channel"; - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[]{ - new Requirement(ACTIVITIES_CHANNEL, 1, "Missing Activities Channel (#activities)") - }; - } - - public void checkResources(){ - if(!TechDiscordBot.getBot().getSpigotStatus().isUsable()) - return; - - TechDiscordBot.getSpigotAPI().getSpigotResources().forEach(resource -> { - Plugin plugin = Plugin.fromId(resource.getId()); - if (plugin == null) - return; - - Update latestUpdate = plugin.getLatestUpdate(); - boolean isNewUpdate = isNewUpdate(resource.getId(), latestUpdate.getId()); - if(isNewUpdate){ - printUpdate(plugin, latestUpdate); - } - }); - } - - public boolean isNewUpdate(String resourceId, String updateId){ - Storage s = TechDiscordBot.getStorage(); - if(s.lastPluginExists(resourceId)){ - String latestUpdate = s.getLastPluginUpdate(resourceId); - if(!Objects.equals(updateId, latestUpdate)){ - s.updateLastPluginUpdate(resourceId, updateId); - return true; - }else{ - return false; - } - }else{ - s.insertLastPluginUpdate(resourceId, updateId); - return true; - } - } - - public void printUpdate(Plugin plugin, Update update) { - TechEmbedBuilder ceb = new TechEmbedBuilder("Update for " + update.getResource().getName()) - .color(plugin.getColor()) - .thumbnail(plugin.getResourceLogo()); - ceb.field("Version", update.getResource().getVersion(), true); - ceb.field("Download", "[Click Here](https://www.spigotmc.org/resources/" + update.getResourceId() + "/update?update=" + update.getId() + ")", true); - ceb.text((update.getDescription().trim().length() > 0 ? update.getTitle() + "```" + update.getDescription() + "```" : update.getTitle())); - - plugin.getChannel().ifPresent(channel -> { - new TechEmbedBuilder().text("There's a new update for " + plugin.getEmoji().getAsMention() + " " + plugin.getRoleName() + "! Make sure to download it [here](https://www.spigotmc.org/resources/" + update.getResourceId() + "/update?update=" + update.getId() + ")!" + - "\n\nCheck out " + ACTIVITIES_CHANNEL.query().first().getAsMention() + " for more info!").queue(channel); - }); - - if(update.getImages() != null && update.getImages().length > 0 && !update.getImages()[0].isEmpty()) ceb.image(update.getImages()[0]); - ceb.queue(ACTIVITIES_CHANNEL.query().first()); - } - - public void printReview(Plugin plugin, Review review) { - StringBuilder ratingSB = new StringBuilder(); - for(int i = 0; i < review.getRating(); ++i) ratingSB.append(":star:"); - Verification verification = TechDiscordBot.getStorage().retrieveVerificationWithSpigot(review.getUser().getUserId()); - - boolean isVerified = verification != null; - boolean isMemberInDiscord = (isVerified && TechDiscordBot.getBot().getMember(verification.getDiscordId()) != null); - String usernameOrAt = (isMemberInDiscord ? TechDiscordBot.getBot().getMember(verification.getDiscordId()).getAsMention() : review.getUser().getUsername()); - - new TechEmbedBuilder("Review from " + review.getUser().getUsername()) - .color(plugin.getColor()) - .thumbnail(review.getResource().getIcon()) - .field("Rating", ratingSB.toString(), true) - .text("```" + review.getText() + "```\nThanks to " + usernameOrAt + " for making this review!") - .queue(ACTIVITIES_CHANNEL.query().first()); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ChatLogModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ChatLogModule.java deleted file mode 100644 index 4a435943..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ChatLogModule.java +++ /dev/null @@ -1,101 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.message.guild.GuildMessageDeleteEvent; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.util.HashMap; - -public class ChatLogModule extends Module { - - private final DefinedQuery CHATLOGS_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getChannels("chat-logs"); - } - }; - - private final HashMap cachedMessages = new HashMap<>(); - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - public ChatLogModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() {} - - @Override - public void onDisable() {} - - @SubscribeEvent - public void onMessage(GuildMessageReceivedEvent e) { - if(e.getMember() == null || e.getMember().getUser().isBot()) return; - if(e.getMember().getRoles().stream().anyMatch(r -> r.getName().equals("Staff"))) return; - - cachedMessages.put(e.getMessageId(), e.getMessage()); - } - - @SubscribeEvent - public void onMessageEdit(GuildMessageUpdateEvent e) { - if(e.getMember() == null || e.getMember().getUser().isBot()) return; - if(e.getMember().getRoles().stream().anyMatch(r -> r.getName().equals("Staff"))) return; - - Message oldMessage = cachedMessages.get(e.getMessageId()); - if(oldMessage == null) return; - - new TechEmbedBuilder("Message Edited") - .text("Message Edited by " + e.getMember().getAsMention() + " in " + e.getMessage().getTextChannel().getAsMention() + ".") - .field("From", oldMessage.getContentRaw(), false) - .field("To", e.getMessage().getContentRaw(), false) - .queue(CHATLOGS_CHANNEL.query().first()); - - cachedMessages.put(e.getMessageId(), e.getMessage()); - } - - @SubscribeEvent - public void onMessageDelete(GuildMessageDeleteEvent e) { - Message message = cachedMessages.get(e.getMessageId()); - if(message == null) return; - - if(message.getMember() == null || message.getMember().getUser().isBot()) return; - if(message.getMember().getRoles().stream().anyMatch(r -> r.getName().equals("Staff"))) return; - - new TechEmbedBuilder("Message Deleted") - .text("Message by " + message.getMember().getAsMention() + " was deleted.") - .field("Text Channel", e.getChannel().getAsMention(), true) - .field("Message", message.getContentRaw(), true) - .queue(CHATLOGS_CHANNEL.query().first()); - - cachedMessages.remove(e.getMessageId()); - } - - @Override - public String getName() { - return "Chat Log"; - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[] { - new Requirement(CHATLOGS_CHANNEL, 1, "Missing Chat Logs Channel (#chatlogs)"), - new Requirement(STAFF_ROLE, 1, "Missing 'Staff' Role") - }; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/EventsModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/EventsModule.java deleted file mode 100644 index 89c2846d..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/EventsModule.java +++ /dev/null @@ -1,64 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.logs.ServerLogs; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.events.guild.GuildBanEvent; -import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent; -import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -public class EventsModule extends Module { - - public EventsModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() {} - - @SubscribeEvent - public void memberJoin(GuildMemberJoinEvent e) { - ServerLogs.log( - new TechEmbedBuilder("Member Joined!") - .success() - .text("Welcome " + e.getMember().getAsMention() + " (" + e.getUser().getName() + "#" + e.getUser().getDiscriminator() + ", " + e.getUser().getId() + ")") - .thumbnail(e.getMember().getUser().getAvatarUrl()) - ); - } - - @SubscribeEvent - public void memberLeave(GuildMemberRemoveEvent e) { - ServerLogs.log( - new TechEmbedBuilder("Member Left!") - .error() - .text(e.getUser().getAsMention() + " (" + e.getUser().getName() + "#" + e.getUser().getDiscriminator() + ", " + e.getUser().getId() + ")") - .thumbnail(e.getUser().getAvatarUrl()) - ); - } - - @SubscribeEvent - public void memberBan(GuildBanEvent e) { - ServerLogs.log( - new TechEmbedBuilder("Member Banned!") - .error() - .text("Don't say goodbye to " + e.getUser().getAsMention() + " (" + e.getUser().getName() + "#" + e.getUser().getDiscriminator() + ", " + e.getUser().getId() + ")") - .thumbnail(e.getUser().getAvatarUrl()) - ); - } - - @Override - public void onDisable() {} - - @Override - public String getName() { - return "Events"; - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[0]; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/PluginLabModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/PluginLabModule.java deleted file mode 100644 index 49636d54..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/PluginLabModule.java +++ /dev/null @@ -1,158 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.github.GitHubUtil; -import me.TechsCode.TechDiscordBot.github.GithubRelease; -import me.TechsCode.TechDiscordBot.logs.ServerLogs; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.PermissionOverride; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import org.apache.commons.text.WordUtils; - -import java.io.IOException; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -public class PluginLabModule extends Module { - - private HashMap plugins = new HashMap<>(); - - private final HashMap lastUpload = new HashMap<>(); - - public PluginLabModule(TechDiscordBot bot) { - super(bot); - } - - public HashMap updatePlugins() { - plugins = new HashMap<>(); - - Objects.requireNonNull(TechDiscordBot.getJDA().getCategoriesByName("\uD83E\uDDEA︱Plugin Lab", true).get(0)).getTextChannels().stream().filter(Objects::nonNull).filter(channel -> channel.getName().endsWith("-lab")).forEach(channel -> { - String pluginName; - - if(channel.getTopic() != null) { - pluginName = channel.getTopic().replace(" Lab", "").replace(" FREE", ""); - } else { - pluginName = channel.getName().replace("-lab", "").replace("-", ""); - } - - plugins.put(pluginName, channel); - }); - - return plugins; - } - - @Override - public void onEnable() { - new Thread(() -> { - while (true) { - updatePlugins(); - detectRelease(); - - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(2)); //Wait every 2 mins - } catch (Exception ignored) {} - } - }).start(); - - new Thread(() -> { - while (true) { - updatePermissions(); - - try { - Thread.sleep(TimeUnit.SECONDS.toMillis(10)); //Wait every 10 seconds - } catch (Exception ignored) {} - } - }).start(); - } - - public void updatePermissions() { - for(Member member : TechDiscordBot.getGuild().getMembers()) { - List roles = member.getRoles().stream().map(Role::getName).collect(Collectors.toList()); - if(roles.contains("Staff")) continue; //Skip staff. - if(!roles.contains("Verified")) continue; //Skip non-verified users. - - plugins.forEach((plugin, channel) -> { - PermissionOverride permOv = channel.getPermissionOverride(member); - boolean canSeeChannel = false; - if(permOv != null) canSeeChannel = permOv.getAllowed().size() > 0 && permOv.getDenied().size() == 0; - - if(roles.contains("Plugin Lab") && (channel.getTopic() != null && channel.getTopic().endsWith("Lab FREE") || roles.contains(plugin)) && !canSeeChannel) { - Collection permissions = new ArrayList<>(Arrays.asList(Permission.MESSAGE_ADD_REACTION, Permission.MESSAGE_READ, Permission.MESSAGE_HISTORY, Permission.MESSAGE_WRITE, Permission.MESSAGE_ATTACH_FILES, Permission.MESSAGE_EMBED_LINKS)); - channel.getManager().putPermissionOverride(member, permissions, new ArrayList<>()).queue(); - - TechDiscordBot.log("Plugin Lab » Added " + member.getEffectiveName() + " to the " + plugin + "'s Lab."); - ServerLogs.log("Plugin Lab", "Added " + member.getAsMention() + " to the " + plugin + "'s Lab."); - } else if(!roles.contains("Plugin Lab") && canSeeChannel) { - channel.getManager().removePermissionOverride(member).queue(); - - TechDiscordBot.log("Plugin Lab » Removed " + plugin + " Lab from (" + member.getEffectiveName() + ")"); - ServerLogs.log("Plugin Lab", "Removed " + plugin + " Lab from (" + member.getAsMention() + ")"); - } - }); - } - } - - public void detectRelease() { - plugins.forEach((name, channel) -> { - String plugin = name.replace(" ", ""); - - GithubRelease release = GitHubUtil.getLatestRelease(plugin); - - if(release != null) { - try { - Date date = release.getRelease().getCreatedAt(); - - if (lastUpload.containsKey(plugin)) { - long lastTime = lastUpload.get(plugin); - if (lastTime != date.getTime()) { - lastUpload.put(plugin, date.getTime()); - uploadFile(channel, release, plugin); - } - } else { - lastUpload.put(plugin, date.getTime()); - } - } catch (IOException ex) { - TechDiscordBot.log("Could not get the last release date from the " + plugin + " repo!"); - } - } else { - TechDiscordBot.log("Could not get info from the " + plugin + " repo!"); - } - }); - } - - public void uploadFile(TextChannel channel, GithubRelease release, String pluginName) { - try { - channel.getHistory().retrieveFuture(100).queue(msgs -> msgs.stream().filter(msg -> msg.getAuthor().isBot() && msg.isPinned()).forEach(msg -> msg.unpin().queue())); - } catch (IllegalStateException ignored) { } - - if(release.getAsset() != null && release.getRelease() != null && release.getFile() != null) { - new TechEmbedBuilder("Ready to Test: " + WordUtils.capitalize(release.getRelease().getName().replace(".jar", ""))) - .text("```" + (release.getRelease().getBody().isEmpty() ? "No changes specified." : release.getRelease().getBody().replaceAll(" \\|\\| ", "\n")) + "```") - .queue(channel); - - channel.sendFile(release.getFile(), pluginName + ".jar").queueAfter(3, TimeUnit.SECONDS, (msg) -> { - msg.pin().queue(); - release.getFile().delete(); - }); - } - } - - @Override - public void onDisable() {} - - @Override - public String getName() { - return "Plugin Lab"; - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[0]; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/PreorderModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/PreorderModule.java deleted file mode 100644 index cfab1557..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/PreorderModule.java +++ /dev/null @@ -1,83 +0,0 @@ -//package me.TechsCode.TechDiscordBot.module.modules; -// -//import me.TechsCode.TechDiscordBot.TechDiscordBot; -//import me.TechsCode.TechDiscordBot.module.Module; -//import me.TechsCode.TechDiscordBot.mysql.storage.Preorder; -//import me.TechsCode.TechDiscordBot.objects.Requirement; -//import net.dv8tion.jda.api.entities.Member; -//import net.dv8tion.jda.api.entities.Role; -// -//import java.util.ArrayList; -//import java.util.List; -//import java.util.concurrent.TimeUnit; -//import java.util.stream.Collectors; -// -//public class PreorderModule extends Module { -// -// private List roles = new ArrayList<>(); -// -// public PreorderModule(TechDiscordBot bot) { -// super(bot); -// } -// -// @Override -// public void onEnable() { -// new Thread(() -> { -// while (true) { -// updateRoles(); -// -// try { -// Thread.sleep(TimeUnit.MINUTES.toMillis(5)); //Wait every 5 minutes -// } catch (Exception ignored) {} -// } -// }).start(); -// -// new Thread(() -> { -// while (true) { -// updateRolesMembers(); -// -// try { -// Thread.sleep(TimeUnit.SECONDS.toMillis(10)); //Wait every 10 seconds -// } catch (Exception ignored) {} -// } -// }).start(); -// } -// -// public void updateRoles() { -// roles = TechDiscordBot.getJDA().getRoles().stream().filter(role -> role.getName().endsWith(" Preorder")).map(Role::getName).collect(Collectors.toList()); -// } -// -// public void updateRolesMembers() { -// if(roles.size() == 0) return; -// -// for(String roleS : roles) { -// if(!bot.getRoles(roleS).hasAny()) continue; -// String pluginName = roleS.replace(" Preorder", ""); -// -// List preorders = new ArrayList<>(TechDiscordBot.getStorage().getPreorders(pluginName, false)); -// -// for(Preorder preorder : preorders) { -// Member member = bot.getMember(String.valueOf(preorder.getDiscordId())); -// if(member == null) continue; -// -// if(member.getRoles().stream().anyMatch(r -> r.getName().equals(roleS))) continue; -// -// Role role = bot.getRoles(roleS).first(); -// TechDiscordBot.getGuild().addRoleToMember(member, role).queue(); -// } -// } -// } -// -// @Override -// public void onDisable() {} -// -// @Override -// public String getName() { -// return "Preorder"; -// } -// -// @Override -// public Requirement[] getRequirements() { -// return new Requirement[0]; -// } -//} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ReactionModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ReactionModule.java deleted file mode 100644 index 03448cfa..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ReactionModule.java +++ /dev/null @@ -1,115 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Emote; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.util.function.Consumer; - -public class ReactionModule extends Module { - - public Message reactionMessage; - - private final TextChannel ROLES_CHANNEL = bot.getChannels("\uD83D\uDCD6︱role-selector").get(0); - - public ReactionModule(TechDiscordBot bot) { - super(bot); - } - - public void onEnable() { - clearMessages(msg -> sendMessage(this::resetReactions)); - } - - public void onDisable() { - this.reactionMessage.delete().complete(); - } - - public void clearMessages(Consumer message) { - ROLES_CHANNEL.getIterableHistory() - .takeAsync(5) - .thenAccept(msg -> { - ROLES_CHANNEL.purgeMessages(msg); - message.accept(null); - }); - } - - public void sendMessage(Consumer message) { - new TechEmbedBuilder("Reaction Roles") - .text(getUpdateEmote().getAsMention() + " **For Plugin Updates**\nWhen there is a new update, you will be notified.\n\n" + getAnnouncementEmote().getAsMention() + " **For Announcements**\nWhen there is an announcement, you will receive a ping.\n\n" + getPatreonNewsEmote().getAsMention() + " **For Patreon News**\nWhen there are any new Benefits, Events and more, you will receive a ping.\n\n" + getGiveawayEmote().getAsMention() + " **For Giveaways**\nWhen there is a giveaway, you will be notified.") - .queue(ROLES_CHANNEL, msg -> { - message.accept(msg); - setReactionMessage(msg); - }); - } - - public void setReactionMessage(Message reactionMessage) { - this.reactionMessage = reactionMessage; - } - - public void resetReactions(Message message) { - message.clearReactions().queue(a -> message.addReaction(getUpdateEmote()).queue(a2 -> message.addReaction(getAnnouncementEmote()).queue(a3 -> message.addReaction(getPatreonNewsEmote()).queue(a4 -> message.addReaction(getGiveawayEmote()).queue())))); - } - - public Emote getAnnouncementEmote() { - return TechDiscordBot.getJDA().getEmoteById("837724632655986718"); - } - - public Emote getUpdateEmote() { - return TechDiscordBot.getJDA().getEmoteById("837724632739217418"); - } - - public Emote getGiveawayEmote() { - return TechDiscordBot.getJDA().getEmoteById("837724632529895486"); - } - - public Emote getPatreonNewsEmote() { return TechDiscordBot.getJDA().getEmoteById("873383006520356964"); } - - @SubscribeEvent - public void onReactionAdd(MessageReactionAddEvent e) { - if (e.getUser() == null || e.getMember() == null) return; - if (e.getUser().isBot()) return; - - if (e.getMessageId().equals(this.reactionMessage.getId())) { - if (e.getMember().getRoles().stream().anyMatch(r -> r.getName().equalsIgnoreCase(e.getReactionEmote().getName()))) { - e.getGuild().removeRoleFromMember(e.getMember(), removeRole(e.getReactionEmote().getName())).queue(); - TechDiscordBot.log("Reaction Role » Removed " + e.getReactionEmote().getName() + " (" + e.getMember().getEffectiveName() + ")"); - - new TechEmbedBuilder("Reaction Roles") - .text("The {role} Role has been removed, you will not be notified whenever there is a {role}.\nSimply react to add the {role} role again, and it will be added.".replace("{role}", e.getReactionEmote().getName())) - .queue(e.getMember()); - } else { - e.getGuild().addRoleToMember(e.getMember(), giveRole(e.getReactionEmote().getName())).queue(); - TechDiscordBot.log("Reaction Role » Added " + e.getReactionEmote().getName() + " (" + e.getMember().getEffectiveName() + ")"); - - new TechEmbedBuilder("Reaction Roles") - .text("The {role} Role has been added, you will now be notified whenever there are {role}.\nSimply react to remove the {role} role again, and it will be removed.".replace("{role}", e.getReactionEmote().getName())) - .queue(e.getMember()); - } - - e.getReaction().removeReaction(e.getUser()).complete(); - } - } - - public Role removeRole(String role) { - return TechDiscordBot.getJDA().getGuildById("311178000026566658").getRolesByName(role, true).get(0); - } - - public Role giveRole(String role) { - return TechDiscordBot.getJDA().getGuildById("311178000026566658").getRolesByName(role, true).get(0); - } - - public String getName() { - return null; - } - - public Requirement[] getRequirements() { - return new Requirement[0]; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/RoleAssignerModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/RoleAssignerModule.java deleted file mode 100644 index 69ad03c8..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/RoleAssignerModule.java +++ /dev/null @@ -1,181 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.mysql.storage.Verification; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.songoda.SongodaPurchase; -import me.TechsCode.TechDiscordBot.spigotmc.data.Resource; -import me.TechsCode.TechDiscordBot.util.Plugin; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Role; - -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -public class RoleAssignerModule extends Module { - - private final DefinedQuery VERIFICATION_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Verified"); - } - }; - - private final DefinedQuery SONGODA_VERIFICATION_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Songoda"); - } - }; - - private final DefinedQuery REVIEW_SQUAD_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Review Squad"); - } - }; - - private final DefinedQuery RESOURCE_ROLES = new DefinedQuery() { - @Override - protected Query newQuery() { - String[] resourceNames = Arrays.stream(Plugin.values()).map(Plugin::getRoleName).toArray(String[]::new); - return bot.getRoles(resourceNames); - } - }; - - private final DefinedQuery SUB_VERIFIED_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Sub Verified"); - } - }; - - public RoleAssignerModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() { - new Thread(() -> { - while (true) { - loop(); - - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(2)); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } - }).start(); - } - - @Override - public void onDisable() {} - - @Override - public String getName() { - return "Role Assigner"; - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[] { - new Requirement(VERIFICATION_ROLE, 1, "Missing 'Verified' Role"), - new Requirement(SONGODA_VERIFICATION_ROLE, 1, "Missing 'Songoda-Verified' Role"), - new Requirement(REVIEW_SQUAD_ROLE, 1, "Missing 'Review Squad' Role"), - new Requirement(RESOURCE_ROLES, 1, "Missing Resource Roles") - }; - } - - public void loop() { - if(!TechDiscordBot.getBot().getSpigotStatus().isUsable() || TechDiscordBot.getSpigotAPI().getSpigotPurchases().size() < 9000 || !TechDiscordBot.getSongodaAPI().isLoaded()) - return; - - Role verificationRole = VERIFICATION_ROLE.query().first(); - Role songodaVerificationRole = SONGODA_VERIFICATION_ROLE.query().first(); - Role reviewSquad = REVIEW_SQUAD_ROLE.query().first(); - - Set verifications = TechDiscordBot.getStorage().retrieveVerifications(); - Set possibleRoles = new HashSet<>(); - - possibleRoles.add(verificationRole); - possibleRoles.add(songodaVerificationRole); - possibleRoles.add(reviewSquad); - possibleRoles.addAll(RESOURCE_ROLES.query().all()); - - Resource[] resources = TechDiscordBot.getSpigotAPI().getSpigotResources().stream().filter(Resource::isPremium).toArray(Resource[]::new); - - HashMap> resourcePurchaserIds = new HashMap<>(); - HashMap> resourceReviewerIds = new HashMap<>(); - - Arrays.stream(resources).forEach(resource -> { - resourcePurchaserIds.put(resource.getId(), resource.getPurchases().stream().map(p -> p.getUser().getUserId()).collect(Collectors.toList())); - resourceReviewerIds.put(resource.getId(), resource.getReviews().stream().map(r -> r.getUser().getUserId()).collect(Collectors.toList())); - }); - - for(Member member : TechDiscordBot.getGuild().getMembers()) { - Verification verification = verifications.stream().filter(v -> v.getDiscordId().equals(member.getUser().getId())).findAny().orElse(null); - Set rolesToKeep = new HashSet<>(); - - if(verification != null) { - rolesToKeep.add(verificationRole); - int purchases = 0, reviews = 0; - - for(Resource resource : resources) { - Role role = bot.getRoles(resource.getName()).first(); - boolean purchased = resourcePurchaserIds.get(resource.getId()).contains(verification.getUserId()); - boolean reviewed = resourceReviewerIds.get(resource.getId()).contains(verification.getUserId()); - - if(purchased) purchases++; - if(reviewed) reviews++; - if(purchased) rolesToKeep.add(role); - } - - if(purchases != 0 && purchases == reviews) rolesToKeep.add(reviewSquad); - } - - for (SongodaPurchase songodaPurchase : TechDiscordBot.getSongodaAPI().getSpigotPurchases().discord(member)) { - rolesToKeep.add(songodaVerificationRole); - rolesToKeep.add(bot.getRoles(songodaPurchase.getResource().getName()).first()); - } - - /*if(TechDiscordBot.getStorage().isSubVerifiedUser(member.getId())) { - if(TechDiscordBot.getStorage().getVerifiedIdFromSubVerifiedId(member.getId()) != null && TechDiscordBot.getGuild().getMemberById(TechDiscordBot.getStorage().getVerifiedIdFromSubVerifiedId(member.getId())) != null) { - TechDiscordBot.getGuild().addRoleToMember(member, SUB_VERIFIED_ROLE.query().first()).queue(); - } else { - TechDiscordBot.getGuild().removeRoleFromMember(member, SUB_VERIFIED_ROLE.query().first()).queue(); - } - } else { - if(member.getRoles().contains(SUB_VERIFIED_ROLE.query().first())) { - TechDiscordBot.getGuild().removeRoleFromMember(member, SUB_VERIFIED_ROLE.query().first()).queue(); - } - }*/ - - Set rolesToRemove = new HashSet<>(); - - if(member.getRoles().stream().map(Role::getName).noneMatch(r -> r.equals("Keep Roles"))) - rolesToRemove = possibleRoles.stream() - .filter(role -> !rolesToKeep.contains(role)) - .filter(role -> member.getRoles().contains(role)) - .collect(Collectors.toSet()); - - Set rolesToAdd = rolesToKeep.stream() - .filter(role -> !member.getRoles().contains(role)) - .collect(Collectors.toSet()); - - rolesToAdd.forEach(r -> { - TechDiscordBot.getGuild().addRoleToMember(member, r).complete(); - TechDiscordBot.log("Role » Added " + r.getName() + " (" + member.getEffectiveName() + ")"); - }); - - rolesToRemove.forEach(r -> { - TechDiscordBot.getGuild().removeRoleFromMember(member, r).complete(); - TechDiscordBot.log("Role » Removed " + r.getName() + " (" + member.getEffectiveName() + ")"); - }); - } - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ServerStatusModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ServerStatusModule.java deleted file mode 100644 index a4e5f9ff..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/ServerStatusModule.java +++ /dev/null @@ -1,57 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - - -public class ServerStatusModule extends Module { - - private boolean mentioned = false; - - public ServerStatusModule(TechDiscordBot bot) { - super(bot); - } - - @SubscribeEvent - public void receive(GuildMessageReceivedEvent e) { - if(!e.getAuthor().getId().equals("984490396799336548")) { - return; - } - if(!e.getMessage().getContentRaw().contains("is now DOWN")){ - return; - } - if(mentioned){ - return; - } - e.getChannel().sendMessage("<@&774690360836096062>").queue(); - new Thread() { - public void run() { - mentioned = true; - try { - Thread.sleep(60000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - mentioned = false; - } - }.start(); - } - - @Override - public void onEnable() {} - - @Override - public void onDisable() {} - - @Override - public String getName() { return "Developer Tag"; } - - @Override - public Requirement[] getRequirements() { - return new Requirement[0]; - } - -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/StaffEmbedModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/StaffEmbedModule.java deleted file mode 100644 index 51a93842..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/StaffEmbedModule.java +++ /dev/null @@ -1,94 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.awt.*; - -public class StaffEmbedModule extends Module { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - public StaffEmbedModule(TechDiscordBot bot) { - super(bot); - } - - @SubscribeEvent - public void receive(GuildMessageReceivedEvent e) { - if(e.getMember() == null) return; - if(e.getAuthor().isBot()) return; - if(!e.getMember().getRoles().contains(STAFF_ROLE.query().first())) return; - - String message = e.getMessage().getContentRaw(); - - if(message.startsWith("^^ ") && message.endsWith(" ^^")) { - e.getMessage().delete().queue(); - - String text = message.substring(3, message.length() - 3); - e.getChannel().sendMessage(text).queue(); - return; - } - - if(message.startsWith("^ ")) { - e.getMessage().delete().queue(); - - String text = message.substring(2); - String[] arguments = text.split("\\^"); - - if(arguments.length != 2 && arguments.length != 3) { - new TechEmbedBuilder("Invalid Arguments").text("Usage: ^ Title ^ Message ^ (Optional) Thumbnail ^").error().sendTemporary(e.getChannel(), 5); - return; - } - - if(arguments.length == 3) { - if (arguments[2].trim().startsWith("#")) { - new TechEmbedBuilder(arguments[0]) - .footer("Posted by " + e.getAuthor().getName()) - .text(arguments[1]) - .color(Color.decode(arguments[2].trim())) - .queue(e.getChannel()); - } else { - new TechEmbedBuilder(arguments[0]) - .footer("Posted by " + e.getAuthor().getName()) - .text(arguments[1]) - .thumbnail(arguments[2]) - .queue(e.getChannel()); - } - - } else { - new TechEmbedBuilder(arguments[0]) - .footer("Posted by " + e.getAuthor().getName()) - .text(arguments[1]) - .queue(e.getChannel()); - } - } - } - - @Override - public void onEnable() {} - - @Override - public void onDisable() {} - - @Override - public String getName() { return "Staff Embed"; } - - @Override - public Requirement[] getRequirements() { - return new Requirement[] { - new Requirement(STAFF_ROLE, 1, "Missing 'Staff' Role") - }; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/SupportWrongChannelModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/SupportWrongChannelModule.java deleted file mode 100644 index 025757b1..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/SupportWrongChannelModule.java +++ /dev/null @@ -1,143 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.mysql.storage.Verification; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.Plugin; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.events.message.guild.react.GuildMessageReactionAddEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.stream.Collectors; - -public class SupportWrongChannelModule extends Module { - - private final DefinedQuery GENERAL_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getChannels("general"); - } - }; - - private final DefinedQuery PLUGIN_DISCUSSION_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getChannels("plugin-discussion"); } }; - - private final DefinedQuery CODING_HELP = new DefinedQuery() { - @Override - protected Query newQuery() { return bot.getChannels("coding-help"); } }; - - public String[] triggerWords = new String[]{"ultra", "i need", "how can i", "help me", "how do i", "how does", "uperms", "ucustomizer", "customizer", "permissions", "regions", "economy", "insane shops", "insaneshops", "can i", "uboards", "scoreboards", "upun", "punishments", "upc", "uecon", "uregions", "urtp", "shops"}; - - public SupportWrongChannelModule(TechDiscordBot bot) { - super(bot); - } - - private final HashMap messages = new HashMap<>(); - - @Override - public void onEnable() {} - - @Override - public void onDisable() {} - - @Override - public String getName() { - return "Support in Wrong Channel"; - } - - @SubscribeEvent - public void onMessage(GuildMessageReceivedEvent e) { - if (e.getMember() == null) return; - if (e.getAuthor().isBot()) return; - if (e.getMember().getRoles().stream().anyMatch(r -> r.getName().equalsIgnoreCase("Staff"))) return; - - if (e.getChannel().getId().equals(GENERAL_CHANNEL.query().first().getId()) || e.getChannel().getId().equals(PLUGIN_DISCUSSION_CHANNEL.query().first().getId()) || e.getChannel().getId().equals(CODING_HELP.query().first().getId())) { - if (Arrays.stream(triggerWords).anyMatch(word -> e.getMessage().getContentDisplay().toLowerCase().contains(word))) { - triggerMessage(e.getMessage(), e.getMember()); - } - } - } - - @SubscribeEvent - public void onReaction(GuildMessageReactionAddEvent e) { - if(e.getUser().isBot()) return; - if(messages.containsKey(e.getMessageId())) { - String memberId = e.getMember().getId(); - if (messages.get(e.getMessageId()).equals(memberId) || e.getMember().getRoles().stream().anyMatch(r -> r.getName().equalsIgnoreCase("Staff"))) { - messages.remove(e.getMessageId()); - e.getChannel().deleteMessageById(e.getMessageId()).queue(); - } else { - e.getReaction().removeReaction(e.getUser()).queue(); - } - } - } - - public void triggerMessage(Message sentMessage, Member member) { - if (messages.containsValue(member.getId())) return; - - TextChannel verificationChannel = bot.getChannel("907349490556616745"); - TechEmbedBuilder teb = new TechEmbedBuilder() - .text("Hello, " + member.getAsMention() + "! I've detected that you might be trying to get help in this channel! To verify your purchase, we ask you to fill out this [form](https://forms.gle/PBX7z5LaXqdYh7wF6) in order to get help, thanks!\n\n*If you are not trying to get help, you can delete this message by reacting to it!*") - .error(); - -// TextChannel verificationChannel = bot.getChannel("907349490556616745"); -// TechEmbedBuilder teb = new TechEmbedBuilder() -// .text("Hello, " + member.getAsMention() + "! I've detected that you might be trying to get help in this channel! Please verify in " + verificationChannel.getAsMention() + " in order to get help, thanks!\n\n*If you are not trying to get help, you can delete this message by reacting to it!*") -// .error(); - - Message message; - Verification verification = TechDiscordBot.getStorage().retrieveVerificationWithDiscord(member); - if (verification != null) { - List pc = Arrays.stream(Plugin.values()).filter(p -> member.getRoles().stream().anyMatch(r -> r.getName().equals(p.getRoleName()))).collect(Collectors.toList()); - - if (pc.size() > 0) { - StringBuilder sb = new StringBuilder(); - String plugins = Plugin.getEmotesByList(pc.stream().map(Plugin::getRoleName).collect(Collectors.toList())); - - sb.append("Hello, ") - .append(member.getAsMention()) - .append("!\n\n It looks like you have bought ") - .append(pc.size() == 1 ? "this plugin" : "these plugins") - .append(" already: ") - .append(plugins) - .append("\nHere are the corresponding channels:\n\n"); - - StringBuilder channels = new StringBuilder(); - pc.forEach(p -> channels.append("- ").append(TechDiscordBot.getJDA().getTextChannelById(p.getChannelId()).getAsMention()).append("\n")); - - sb.append(channels.toString()); - sb.append("\nPlease use the corresponding plugin channel above to get support.\nThis channel is **not** a support channel.\n\n*If you are not trying to get help, you can delete this message by reacting to it!*"); - - message = new TechEmbedBuilder().text(sb.toString()).error().reply(sentMessage); - } else { - message = teb.reply(sentMessage); - } - } else { - message = teb.reply(sentMessage); - } - - if (message != null) { - message.addReaction("\u274C").queue(); - messages.put(message.getId(), member.getId()); - } - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[]{ - new Requirement(GENERAL_CHANNEL, 1, "Could not find #general"), - new Requirement(PLUGIN_DISCUSSION_CHANNEL, 1, "Could not find #plugin-discussion"), - new Requirement(CODING_HELP, 1, "Could not find #coding-help") - }; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/TicketModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/TicketModule.java deleted file mode 100644 index c3a7a4e9..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/TicketModule.java +++ /dev/null @@ -1,563 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.logs.TicketLogs; -import me.TechsCode.TechDiscordBot.logs.TranscriptLogs; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.objects.TicketPriority; -import me.TechsCode.TechDiscordBot.transcripts.TicketTranscript; -import me.TechsCode.TechDiscordBot.transcripts.TicketTranscriptOptions; -import me.TechsCode.TechDiscordBot.util.Plugin; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.Permission; -import net.dv8tion.jda.api.entities.*; -import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.events.message.react.MessageReactionAddEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.awt.*; -import java.util.List; -import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; -import java.util.stream.Collectors; - -public class TicketModule extends Module { - - private TextChannel channel; - private Message lastInstructions; - private String selectionUserId; - private TicketPriority selectionPriority; - private Plugin selectionPlugin; - - private boolean isSelection; - private int selectionStep; - private final List CLOSING_CHANNELS = new ArrayList<>(); - - private final DefinedQuery PRIORITY_EMOTES = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getEmotes("low_priority", "medium_priority", "high_priority"); - } - }; - - private final DefinedQuery ERROR_EMOTE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getEmotes("error"); - } - }; - - private final DefinedQuery PLUGIN_EMOTES = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getEmotes(Arrays.stream(Plugin.values()).map(Plugin::getEmojiName).toArray(String[]::new)); - } - }; - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - private final DefinedQuery PATREON_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Patreon"); - } - }; - - private final DefinedQuery SUB_VERIFIED = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Sub Verified"); - } - }; - - private final DefinedQuery TICKET_CATEGORY = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getCategories("\uD83C\uDFAB ︱Tickets"); - } - }; - - private final DefinedQuery TICKET_CREATION_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getChannels("tickets"); - } - }; - - public TicketModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() { - channel = TICKET_CREATION_CHANNEL.query().first(); - channel.getIterableHistory() - .takeAsync(100) - .thenAccept(msg -> channel.purgeMessages(msg.stream().filter(m -> m.getReactions().size() > 0).collect(Collectors.toList()))); - - selectionStep = 1; - lastInstructions = null; - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - if(lastInstructions != null) - lastInstructions.delete().complete(); - })); - - sendPriorityInstructions(null); - } - - @Override - public void onDisable() { - if(lastInstructions != null) - lastInstructions.delete().complete(); - } - - public void sendPriorityInstructions(Member member) { - if(isSelection) return; - selectionStep = 1; - - Emote lowPriority = PRIORITY_EMOTES.query().get(0); - - if(lastInstructions != null) lastInstructions.delete().queue(); - TechEmbedBuilder priority = new TechEmbedBuilder("Ticket Creation" + (member != null ? " (" + member.getEffectiveName() + ")" : "")) - .text("Please react below to create a ticket!"); - - priority.queue(channel, message -> setLastInstructions(message, msg -> { - try { - msg.addReaction(lowPriority).queue(); - } catch (Exception ignored) {} - })); - } - - public void sendPluginInstructions(Member member) { - if(selectionStep != 1) return; - selectionUserId = member.getId(); - isSelection = true; - selectionStep = 2; - - String sb = PLUGIN_EMOTES.query().all().stream().map(emote -> emote.getAsMention() + " - " + Plugin.byEmote(emote).getRoleName()).collect(Collectors.joining("\n")); - - if(lastInstructions != null) lastInstructions.delete().queue(); - TechEmbedBuilder plugin = new TechEmbedBuilder("Ticket Creation (" + member.getEffectiveName() + ")") - .text("Please select which plugin the issue corresponds with below:", "", sb, "", ERROR_EMOTE.query().first().getAsMention() + " - Cancel", ""); - - plugin.queue(channel, message -> setLastInstructions(message, msg -> { - PLUGIN_EMOTES.query().all().stream().filter(emote -> msg != null).forEach(emote -> msg.addReaction(emote).queue((msg2) -> { - try { - msg.addReaction(ERROR_EMOTE.query().first()).queue(); - } catch (Exception ignored) {} - })); - })); - } - - public void sendIssueInstructions(Member member) { - if(selectionStep != 2) - return; - - selectionStep = 3; - isSelection = true; - - if(lastInstructions != null) - lastInstructions.delete().queue(); - - TechEmbedBuilder issue = new TechEmbedBuilder("Ticket Creation (" + member.getEffectiveName() + ")") - .text("Last but not least, please tell us what you're having an issue with!\n\nIn your server, please run the following commands\nand take a screenshot of the information.\n\n__To get the server information__ **>**```/about```\n__To get the plugin information__ **>**```/about ```", "", ERROR_EMOTE.query().first().getAsMention() + " - Cancel", "", "*Try not to make the message over 1024 chars long.*", "*We'll cut it off due to Discord's Limitations!*"); - - issue.queue(channel, message -> setLastInstructions(message, msg -> { - try { - msg.addReaction(ERROR_EMOTE.query().first()).queue(); - } catch (Exception ignored) {} - })); - } - - public void createTicket(Member member, Plugin plugin, String issue) { - String name = "ticket-" + member.getEffectiveName().replaceAll("[^a-zA-Z\\d\\s_-]", "").toLowerCase(); - if(name.equals("ticket-")) - name = "ticket-" + member.getUser().getId(); //Make sure the ticket has an actual name. In case the regex result is empty. - - TextChannel ticketChannel = TechDiscordBot.getGuild().createTextChannel(name) - .setParent(getTicketCategory()) - .setTopic(member.getAsMention() + "'s Ticket | Problem Solved? Please execute /ticket close.") - .complete(); - - ticketChannel.getManager().clearOverridesAdded().complete(); - ticketChannel.getManager().clearOverridesRemoved().complete(); - - List permissionsAllow = new ArrayList<>(Arrays.asList(Permission.MESSAGE_ADD_REACTION, Permission.MESSAGE_ATTACH_FILES, Permission.MESSAGE_EMBED_LINKS, Permission.MESSAGE_READ, Permission.MESSAGE_WRITE, Permission.MESSAGE_HISTORY)); - ticketChannel.getManager() - .putPermissionOverride(STAFF_ROLE.query().first(), permissionsAllow, Collections.singletonList(Permission.MESSAGE_TTS)) - .putPermissionOverride(member, permissionsAllow, Collections.singletonList(Permission.MESSAGE_TTS)) - .putPermissionOverride(TechDiscordBot.getGuild().getPublicRole(), new ArrayList<>(), Arrays.asList(Permission.MESSAGE_READ, Permission.MESSAGE_WRITE)) - .queue(); - - String plugins = Plugin.getMembersPluginsinEmojis(member); - new TechEmbedBuilder(member.getEffectiveName() + " - " + member.getUser().getId()) - .field("Plugin", plugin.getEmoji().getAsMention(), true) - .field("Owned Plugins", plugins, true) - .field("Issue", issue, false) - .queue(ticketChannel); - - if(TechDiscordBot.getStorage().isSubVerifiedUser(member.getId())) { - new TechEmbedBuilder("Sub Verified User Support") - .text("Original Plugin-holder: " + TechDiscordBot.getGuild().getMemberById(TechDiscordBot.getStorage().getVerifiedIdFromSubVerifiedId(member.getId())).getAsMention()) - .color(Color.ORANGE) - .queue(ticketChannel); - } - - TicketLogs.log( - new TechEmbedBuilder("New Ticket") - .text(member.getAsMention() + " created a new ticket (" + ticketChannel.getAsMention() + ")") - ); - - reset(); - } - - public void startTimeout(String userId) { - new Thread(() -> { - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(5)); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - if(this.selectionUserId == null || userId == null) - return; - - if(this.selectionUserId.equals(userId) && isSelection) { - new TechEmbedBuilder("Ticket - Error") - .error() - .text("You took too long!") - .sendTemporary(channel, 10); - - reset(); - } - }).start(); - } - - public boolean isTicketChat(TextChannel channel) { - return channel.getName().contains("ticket-"); - } - - public TextChannel getOpenTicketChat(Member member) { - return TechDiscordBot.getGuild().getTextChannels().stream().filter(channel -> isTicketChat(channel) && channel.getTopic() != null && channel.getTopic().contains(member.getAsMention())).findFirst().orElse(null); - } - - public static Member getMemberFromTicket(TextChannel channel) { - if(channel == null || channel.getTopic() == null) - return null; - - return channel.getGuild().getMemberById(channel.getTopic().split("<")[1].split(">")[0].replace("@", "").replace("!", "")); - } - - public Category getTicketCategory() { - return TICKET_CATEGORY.query().first(); - } - - @SubscribeEvent - public void onReactionAdd(MessageReactionAddEvent e) { - if(e.getUser() == null || e.getMember() == null || e.getUser().isBot() || e.getChannel() != channel) - return; - if((selectionUserId != null && !e.getMember().getId().equals(selectionUserId))) { - e.getReaction().removeReaction(e.getUser()).queue(); - return; - } - - if(getOpenTicketChat(e.getMember()) != null) { - new TechEmbedBuilder("Ticket Creation - Error") - .text("You already have an open ticket (" + getOpenTicketChat(e.getMember()).getAsMention() + ")") - .error() - .sendTemporary(channel, 10); - - reset(); - return; - } - - if(e.getReactionEmote().getName().equalsIgnoreCase("error") && selectionStep != 1) { - reset(); - return; - } - - if(selectionStep == 1 || selectionUserId == null) { - selectionPriority = TicketPriority.valueOf(e.getReactionEmote().getEmote().getName().split("_")[0].toUpperCase()); - sendPluginInstructions(e.getMember()); - startTimeout(e.getMember().getId()); - } else if(selectionStep == 2) { - Plugin plugin = Plugin.byEmote(e.getReactionEmote().getEmote()); - - if (plugin == null) - return; - - if(e.getMember().getRoles().stream().noneMatch(r -> r.getName().equals(plugin.getRoleName())) && !e.getMember().getRoles().contains(SUB_VERIFIED.query().first())) { - new TechEmbedBuilder("Ticket - Error") - .error() - .text("You do not own " + plugin.getRoleName() + "!") - .sendTemporary(channel, 10); - e.getReaction().removeReaction(e.getUser()).queue(); - - return; - } - - selectionPlugin = Plugin.byEmote(e.getReactionEmote().getEmote()); - sendIssueInstructions(e.getMember()); - } else { - String ezMention = TechDiscordBot.getJDA().getUserById("130340486920667136").getAsMention(); - - new TechEmbedBuilder("Ticket Creation - Error") - .text("This shouldn't be happening. Contact " + ezMention + " (EazyFTW#0001) immediately!") - .error() - .sendTemporary(channel, 10); - - reset(); - } - } - - @SubscribeEvent - public void onMessageIssue(GuildMessageReceivedEvent e) { - if(e.getAuthor().isBot()) return; - if(e.getChannel() != channel) return; - if(e.getMember() == null) return; - - if(selectionUserId == null || !e.getMember().getId().equals(selectionUserId) || selectionStep != 3) { - e.getMessage().delete().queue(); - return; - } - - if(!isSelection) - return; - - String message = e.getMessage().getContentDisplay(); - if(message.length() > 1024) - message = message.substring(0, 1024); //Make sure It outputs the embed. Embed values cannot be longer than 1024 chars. - - e.getMessage().delete().queue(); - createTicket(e.getMember(), selectionPlugin, message); - } - - @SubscribeEvent - public void onSlashCommand(SlashCommandEvent e) { - if(e.getMember() == null || e.getMember().getUser().isBot()) - return; - - if(e.getName().equals("ticket") && e.getSubcommandName() != null) { - if(!isTicketChat(e.getTextChannel())) { - e.reply("This channel is not a ticket!").setEphemeral(true).queue(); - return; - } - - boolean isTicketCreator = e.getTextChannel().getTopic() != null && e.getTextChannel().getTopic().contains(e.getMember().getAsMention()); - - if(!isTicketCreator && !TechDiscordBot.isStaff(e.getMember())) { - e.reply("You have to be the ticket creator or a staff member to execute this command!").setEphemeral(true).queue(); - return; - } - - Member member = e.getOption("member") == null ? null : e.getOption("member").getAsMember(); - if(!e.getSubcommandName().equals("transcript") && !e.getSubcommandName().equals("close") && member == null) { - e.reply("**Member is invalid!** This probably shouldn't be happening...").setEphemeral(true).queue(); - return; - } - - switch (e.getSubcommandName()) { - case "transcript": { - if (!TechDiscordBot.isStaff(e.getMember())) { - e.reply("You cannot force a ticket transcript!").setEphemeral(true).queue(); - return; - } - - TicketTranscript transcript = TicketTranscript.buildTranscript(e.getTextChannel(), TicketTranscriptOptions.DEFAULT); - Member ticketMember = getMemberFromTicket(e.getTextChannel()); - - e.reply("Generating the transcript... please wait.").queue(msg -> { - transcript.build(object -> { - if(ticketMember != null) { - TranscriptLogs.log( - new TechEmbedBuilder("Ticket Transcript (Command)") - .text(ticketMember == null ? "Transcript of #" + e.getChannel().getName() + ": " + transcript.getUrl() : "Transcript of " + ticketMember.getAsMention() + "'s ticket:\n" + transcript.getUrl()) - .color(Color.ORANGE) - ); - } - - msg.editOriginalEmbeds( - new TechEmbedBuilder("Ticket Transcript") - .text(ticketMember == null ? "Transcript of #" + e.getChannel().getName() + ": " + transcript.getUrl() : "Transcript of " + ticketMember.getAsMention() + "'s ticket:\n" + transcript.getUrl()) - .color(Color.ORANGE) - .build() - ).queue(); - - TechDiscordBot.getStorage().saveTranscript(object); - }); - }); - } case "add": - if (e.getMember().equals(member)) { - e.reply("You can't be added to a ticket you're already in.").setEphemeral(true).queue(); - return; - } - - e.reply("Successfully added " + member.getAsMention() + " to this ticket!").queue(); - - Collection permissionsAddAllow = new ArrayList<>(Arrays.asList(Permission.MESSAGE_ADD_REACTION, Permission.MESSAGE_ATTACH_FILES, Permission.MESSAGE_EMBED_LINKS, Permission.MESSAGE_READ, Permission.MESSAGE_WRITE, Permission.MESSAGE_HISTORY)); - Collection permissionsAddDeny = new ArrayList<>(Arrays.asList(Permission.MANAGE_THREADS, Permission.USE_PRIVATE_THREADS, Permission.USE_PUBLIC_THREADS)); - e.getTextChannel().getManager().putPermissionOverride(member, permissionsAddAllow, permissionsAddDeny).queue(); - break; - case "remove": - boolean isTicketCreator2 = e.getTextChannel().getTopic() != null && e.getTextChannel().getTopic().contains(member.getAsMention()); - - if (TechDiscordBot.isStaff(member) || isTicketCreator2) { - e.reply(member.getAsMention() + " can't be removed from this ticket!").setEphemeral(true).queue(); - return; - } - - e.reply("Successfully removed " + member.getAsMention() + " from this ticket!").queue(); - - Collection permissionsRemoveDeny = new ArrayList<>(Arrays.asList(Permission.MESSAGE_ADD_REACTION, Permission.MESSAGE_ATTACH_FILES, Permission.MESSAGE_EMBED_LINKS, Permission.MESSAGE_READ, Permission.MESSAGE_WRITE, Permission.MESSAGE_HISTORY)); - e.getTextChannel().getManager().putPermissionOverride(member, new ArrayList<>(), permissionsRemoveDeny).queue(); - break; - case "close": - TicketTranscript transcript = TicketTranscript.buildTranscript(e.getTextChannel(), TicketTranscriptOptions.DEFAULT); - String channelId = e.getChannel().getId(); - - if (isTicketCreator) { - if (CLOSING_CHANNELS.contains(e.getChannel().getId())) { - e.reply("This ticket is already closing!").setEphemeral(true).queue(); - return; - } - - e.replyEmbeds( - new TechEmbedBuilder("Ticket") - .text("Thank you for contacting us " + e.getMember().getAsMention() + ". Consider writing a review if you enjoyed the support!") - .build() - ).queue(); - - transcript.build(object -> { - new TechEmbedBuilder("Transcript") - .text("You can view your recently closed ticket's transcript here:\n" + transcript.getUrl()) - .color(Color.ORANGE) - .queue(e.getMember()); - - TranscriptLogs.log( - new TechEmbedBuilder("Ticket Transcript") - .text("Transcript of " + e.getMember().getAsMention() + "'s ticket:\n" + transcript.getUrl()) - .color(Color.ORANGE) - ); - - e.getTextChannel().delete().queueAfter(15, TimeUnit.SECONDS, s -> CLOSING_CHANNELS.remove(channelId)); - TechDiscordBot.getStorage().saveTranscript(object); - }); - TicketLogs.log( - new TechEmbedBuilder("Solved Ticket") - .text("The ticket (" + e.getTextChannel().getName() + ") created by " + e.getMember().getAsMention() + " is now solved. Thanks for contacting us!") - .success() - ); - } else { - if (!TechDiscordBot.isStaff(e.getMember())) { - e.reply("You cannot close this ticket!").setEphemeral(true).queue(); - return; - } - - if (CLOSING_CHANNELS.contains(e.getChannel().getId())) { - e.reply("This ticket is already closing!").setEphemeral(true).queue(); - return; - } - - String reason = e.getOption("reason") == null ? null : e.getOption("reason").getAsString(); - - boolean hasReason = reason != null; - String reasonSend = (hasReason ? " \n\n**Reason**: " + reason : ""); - - Member ticketMember = getMemberFromTicket(e.getTextChannel()); - - e.replyEmbeds( - new TechEmbedBuilder("Ticket") - .text(e.getMember().getAsMention() + " has closed this support ticket." + reasonSend) - .build() - ).queue(); - - CLOSING_CHANNELS.add(e.getChannel().getId()); - - if (ticketMember != null) { - new TechEmbedBuilder("Ticket Closed") - .text("The ticket (" + e.getTextChannel().getName() + ") from " + ticketMember.getAsMention() + " has been closed!") - .success() - .queueAfter(channel, 15, TimeUnit.SECONDS, (msg) -> reset()); - - if (ticketMember != null) { - new TechEmbedBuilder("Ticket Closed") - .text("Your ticket (" + e.getTextChannel().getName() + ") has been closed!" + reasonSend) - .success() - .queue(ticketMember); - } - } else { - new TechEmbedBuilder("Ticket Closed") - .text("The ticket (" + e.getTextChannel().getName() + ") from *member has left* has been closed!") - .success() - .queueAfter(channel, 15, TimeUnit.SECONDS, (msg) -> reset()); - } - - transcript.build(object -> { - if(ticketMember != null) { - TranscriptLogs.log( - new TechEmbedBuilder("Ticket Transcript") - .text(ticketMember == null ? "Transcript of #" + e.getChannel().getName() + ": " + transcript.getUrl() : "Transcript of " + ticketMember.getAsMention() + "'s ticket:\n" + transcript.getUrl()) - .color(Color.ORANGE) - ); - - if (ticketMember != null) { - new TechEmbedBuilder("Ticket Closed") - .text("Your ticket (" + e.getTextChannel().getName() + ") has been closed!" + reasonSend + "\n\nYou can view the transcript here:\n" + transcript.getUrl()) - .success() - .queue(ticketMember); - } - } - - TechDiscordBot.getStorage().saveTranscript(object); - e.getTextChannel().delete().queueAfter(15, TimeUnit.SECONDS, s -> CLOSING_CHANNELS.remove(channelId)); - }); - } - - break; - default: - e.reply("Could not recognize this sub command!").setEphemeral(true).queue(); - break; - } - } - } - - public void reset() { - isSelection = false; - selectionUserId = null; - sendPriorityInstructions(null); - } - - public void setLastInstructions(Message message) { - this.lastInstructions = message; - } - - public void setLastInstructions(Message message, Consumer after) { - this.lastInstructions = message; - after.accept(this.lastInstructions); - } - - @Override - public String getName() { - return "Tickets"; - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[] { - new Requirement(TICKET_CREATION_CHANNEL, 1, "Missing Creation Channel (#tickets)"), - new Requirement(TICKET_CATEGORY, 1, "Missing Tickets Category (tickets)"), - new Requirement(STAFF_ROLE, 1, "Missing 'Staff' Role") - }; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/UrlWhitelistModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/UrlWhitelistModule.java deleted file mode 100644 index c8fea340..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/UrlWhitelistModule.java +++ /dev/null @@ -1,171 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Category; -import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.awt.*; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class UrlWhitelistModule extends Module { - - private final DefinedQuery STAFF_ROLE = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getRoles("Staff"); - } - }; - - private final DefinedQuery IGNORED_CATEGORIES = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getCategories("\uD83D\uDCC1 | Archives", "\uD83D\uDCD1 | Staff Logs", "Other Staff Discussions", "staff discussions", "⚖ | Leadership-Discussions", "\uD83C\uDFAB ︱Tickets"); - } - }; - - private final List WHITELISTED_URLS = new ArrayList<>(); - private final String URL = "https://raw.githubusercontent.com/TechsCode-Team/TechBot-Whitelists/main/urlWhitelist.txt"; - - public UrlWhitelistModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() { - new Thread(() -> { - while (true) { - getWhitelist(); - - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(10)); - } catch (Exception ignored) { } - } - }).start(); - } - - @Override - public void onDisable() { } - - public String getName() { - return "UrlWhitelistModule"; - } - - @SubscribeEvent - public void onMessage(GuildMessageReceivedEvent e) { - if (e.getMember() == null || e.getAuthor().isBot() || e.getMember().getRoles().contains(STAFF_ROLE.query().first()) || IGNORED_CATEGORIES.query().stream().anyMatch(c -> c.getId().equals(e.getChannel().getParent().getId()))) return; - - boolean block = checkMessage(e.getMessage().getContentRaw()); - if (block) { - e.getMessage().delete().queue(); - new TechEmbedBuilder("Blocked URL(s)") - .color(Color.RED) - .text("Your message contained a URL which is not in our whitelist.\n\nIf you think this is a mistake, take a look at our [**link whitelist**](" + URL + ").") - .sendTemporary(e.getChannel(), 10, TimeUnit.SECONDS); - } - } - - @SubscribeEvent - public void onMessageUpdate(GuildMessageUpdateEvent e) { - if (e.getMember() == null || e.getAuthor().isBot() || e.getMember().getRoles().contains(STAFF_ROLE.query().first()) || IGNORED_CATEGORIES.query().stream().anyMatch(c -> c.getId().equals(e.getChannel().getParent().getId()))) return; - - boolean block = checkMessage(e.getMessage().getContentRaw()); - if (block) { - e.getMessage().delete().queue(); - new TechEmbedBuilder("Blocked URL(s)") - .color(Color.RED) - .text("Your message contained a URL which is not in our whitelist.\n\nIf you think this is a mistake, take a look at our [**link whitelist**](" + URL + ").") - .sendTemporary(e.getChannel(), 10, TimeUnit.SECONDS); - } - } - - private boolean checkMessage(String message){ - boolean blockMessage = false; - if (!WHITELISTED_URLS.isEmpty()) { - Set extractedUrls = extractUrls(message); - blockMessage = extractedUrls.stream().anyMatch(extractedUrl -> !WHITELISTED_URLS.contains(extractedUrl)); - } - return blockMessage; - } - - private void getWhitelist() { - try { - URL url = new URL(URL); - - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("GET"); - - int status = con.getResponseCode(); - - if (status == 200) { - BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); - String inputLine; - - while ((inputLine = in.readLine()) != null) { - String word = inputLine.trim().toLowerCase(); - - if(!WHITELISTED_URLS.contains(word)) - WHITELISTED_URLS.add(word); - } - - in.close(); - } else { - TechDiscordBot.log("ERROR", "Failed to fetch the white listed urls."); - } - - con.disconnect(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private Set extractUrls(String text) { - Set containedUrls = new LinkedHashSet<>(); - - String domain = ""; - boolean successfulParse = false; - - String regex = "(https?://(?:www\\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|www\\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\\.[^\\s]{2,}|https?://(?:www\\.|(?!www))[a-zA-Z0-9]+\\.[^\\s]{2,}|www\\.[a-zA-Z0-9]+\\.[^\\s]{2,})"; - Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); - Matcher m = p.matcher(text); - - while (m.find()) { - String regexResponse = m.group(0); - - try { - URL url = new URL(regexResponse); - String[] domainExploded = url.getHost().split("\\."); - domain = domainExploded[domainExploded.length - 2] + "." + domainExploded[domainExploded.length - 1]; - successfulParse = true; - } catch (Exception ignored) {} - - if(successfulParse) - containedUrls.add(domain); - } - - return containedUrls; - } - - public Requirement[] getRequirements() { - return new Requirement[] { - new Requirement(IGNORED_CATEGORIES, IGNORED_CATEGORIES.query().amount(), "Could not find all of the ignored category channels.") - }; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/VerificationModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/VerificationModule.java deleted file mode 100644 index 3b938104..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/VerificationModule.java +++ /dev/null @@ -1,243 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.logs.VerificationLogs; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.mysql.storage.Verification; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.spigotmc.data.APIStatus; -import me.TechsCode.TechDiscordBot.spigotmc.data.ProfileComment; -import me.TechsCode.TechDiscordBot.spigotmc.data.Purchase; -import me.TechsCode.TechDiscordBot.spigotmc.data.lists.ProfileCommentList; -import me.TechsCode.TechDiscordBot.util.Plugin; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; - -import static me.TechsCode.TechDiscordBot.TechDiscordBot.getJDA; -import static me.TechsCode.TechDiscordBot.TechDiscordBot.getSpigotAPI; - -public class VerificationModule extends Module { - - private final DefinedQuery VERIFICATION_CHANNEL = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getChannels("\uD83D\uDCD8︱verification"); - } - }; - - private TextChannel channel; - private Message lastInstructions; - - private List verificationQueue; - - public VerificationModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() { - channel = VERIFICATION_CHANNEL.query().first(); - channel.getIterableHistory() - .takeAsync(100) - .thenAccept(msg -> channel.purgeMessages(msg.stream().filter(m -> m.getEmbeds().size() > 0 && m.getEmbeds().get(0).getAuthor() != null && m.getEmbeds().get(0).getAuthor().getName() != null && m.getEmbeds().get(0).getAuthor().getName().equals("How It Works")).collect(Collectors.toList()))); - - lastInstructions = null; - verificationQueue = new ArrayList<>(); - - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - if (lastInstructions != null) - lastInstructions.delete().complete(); - })); - - sendInstructions(); - } - - @Override - public void onDisable() { - if (lastInstructions != null) lastInstructions.delete().submit(); - } - - public void sendInstructions() { - if (lastInstructions != null) - lastInstructions.delete().complete(); - - TechEmbedBuilder howItWorksMessage = new TechEmbedBuilder("Manual Verification").text("Hi there,\n" + - "\n" + - "Due to the unavailability of our verification system, we will have to manually authenticate your transactions.\n" + - "\n" + - "To verify your purchase, we ask you to fill out this form [here](https://forms.gle/PBX7z5LaXqdYh7wF6)\n" + - "\n" + - "Once you have filled in the form, we will receive it and review it as fast as possible.\n" + - "\n" + - "*Do not DM or ping any staff member to get verified or ask if it can be done faster*"); - lastInstructions = howItWorksMessage.complete(channel); - } - - @SubscribeEvent - public void onMessage(GuildMessageReceivedEvent e) { - if (e.getMember() == null) return; - if (e.getAuthor().isBot()) return; - if (!e.getChannel().equals(channel)) return; - - String username = e.getMessage().getContentDisplay(); - e.getMessage().delete().complete(); - - TechEmbedBuilder errorMessage = new TechEmbedBuilder("Error (" + e.getAuthor().getName() + ")").error(); - -// if (!TechDiscordBot.getBot().getSpigotStatus().isUsable()) { -// errorMessage.text("**The API is currently offline.**\nThere is no ETA of when it will be back up.\nYou will have to wait to verify until then.").error().sendTemporary(channel, 10); -// -// String msg = "User " + e.getAuthor().getName() + "#" + e.getAuthor().getDiscriminator() + "Tried to verify but the the api is down!"; -// alertMsg(msg); -// -// return; -// } - - if (verificationQueue.contains(e.getAuthor().getId())) { - errorMessage.text("Please follow the instruction above!").sendTemporary(channel, 15); - return; - } - - Verification existingVerification = TechDiscordBot.getStorage().retrieveVerificationWithDiscord(e.getAuthor().getId()); - if (existingVerification != null) { - errorMessage.text("You've already linked to your SpigotMC Account and your roles will be updated automatically!").sendTemporary(channel, 15); - return; - } - - if (username.contains(" ")) { - errorMessage.text("Please type in your SpigotMC Username!").sendTemporary(channel, 5); - return; - } - - Purchase[] purchases = TechDiscordBot.getSpigotAPI().getSpigotPurchases().username(username).toArray(new Purchase[0]); - - if (purchases.length == 0) { - errorMessage.text("User " + e.getAuthor().getName() + "#" + e.getAuthor().getDiscriminator() + " does not own any of Tech's Plugins!\n\n*It may take up to 20 minutes for the bot to recognize new purchases.*\n\n*This could also be an issue with the api. If you believe this is a mistake, please contact a staff member!*"); - - if (TechDiscordBot.getBot().getSpigotStatus() == APIStatus.NOT_FETCHING) { - errorMessage.text(errorMessage.getText() + "\n\n**The API is currently not fetching new information, this could also be the issue."); - - String msg = "User (" + e.getAuthor().getName() + "#" + e.getAuthor().getDiscriminator() + ") tried to verify but the the api is down!"; - alertMsg(msg); - - return; - } - - errorMessage.error().sendTemporary(channel, 10); - return; - } - - username = purchases[0].getUser().getUsername(); - String userId = purchases[0].getUser().getUserId(); - String avatarUrl = purchases[0].getUser().getAvatar(); - - existingVerification = TechDiscordBot.getStorage().retrieveVerificationWithSpigot(userId); - - if (existingVerification != null) { - Purchase purchase = TechDiscordBot.getSpigotAPI().getSpigotPurchases().userId(existingVerification.getUserId()).get(0); - - String msg = "User " + e.getAuthor().getName() + "#" + e.getAuthor().getDiscriminator() + " Has tried to verify as https://www.spigotmc.org/members/" + username.toLowerCase() + "." + userId + " But this user is already verified!"; - alertMsg(msg); - - errorMessage.text("The SpigotMC User " + username + " is already linked with " + purchase.getUser().getUsername() + ". If you believe this is a mistake, please contact a Staff Member.").sendTemporary(channel, 10); - return; - } - - String code = UUID.randomUUID().toString().split("-")[0]; - - TechEmbedBuilder instructions = new TechEmbedBuilder("Verify " + e.getAuthor().getName()) - .thumbnail(avatarUrl) - .text("Now go to your SpigotMC Profile and post `TechVerification." + code + "`\n\nLink to your Profile:\nhttps://www.spigotmc.org/members/" + username.toLowerCase() + "." + userId + "\n\n**Please wait 3 minutes!**"); - - Message m = e.getMessage().getChannel().sendMessage(instructions.build()).complete(); - verificationQueue.add(e.getAuthor().getId()); - String finalUsername = username; - - new Thread(() -> { - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(3)); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - - ProfileCommentList comments = getSpigotAPI().getSpigotProfileComments(finalUsername+"."+userId, false); - - for (ProfileComment all : comments) { - if (all.getText().equals("TechVerification." + code)) { - if (all.getUserId().equals(finalUsername+"."+userId)) { - m.delete().complete(); - - String msg = "User " + e.getAuthor().getName() + "#" + e.getAuthor().getDiscriminator() + " Has verified as https://www.spigotmc.org/members/" + finalUsername.toLowerCase() + "." + userId; - alertMsg(msg); - - VerificationLogs.log( - new TechEmbedBuilder(e.getAuthor().getName() + "'s Verification Completed") - .success().text(e.getAuthor().getName() + " has successfully verified their SpigotMC Account!") - .thumbnail(avatarUrl) - ); - } - - sendInstructions(); - this.verificationQueue.remove(e.getAuthor().getId()); - - if (all.getUserId().equals(finalUsername+"."+userId)) { - TechDiscordBot.getStorage().createVerification(userId, e.getAuthor().getId()); - - new TechEmbedBuilder("Verification Complete!") - .text("You've been successfully verified!\n\nHere are your purchased plugins: " + Plugin.getMembersPluginsinEmojis(e.getMember()) + "\n\n*Your roles will be updated automatically from now on!*") - .thumbnail(avatarUrl) - .queue(e.getMember()); - } else { - String msg = "User " + e.getAuthor().getName() + "#" + e.getAuthor().getDiscriminator() + " Has tried to verify as https://www.spigotmc.org/members/" + finalUsername.toLowerCase() + "." + userId; - alertMsg(msg); - - m.editMessage(errorMessage.text("Please verify your own account.").build()).complete().delete().queueAfter(10L, TimeUnit.SECONDS); - } - - new TechEmbedBuilder() - .text("You may now delete the message on your profile! [Go to Comment](https://www.spigotmc.org/profile-posts/" + all.getCommentId() + ")") - .queue(e.getMember()); - return; - } - } - - verificationQueue.remove(e.getAuthor().getId()); - m.editMessage(errorMessage.text("**You took too long!**\n\nThe Verification process has timed out! Please try again.").build()) - .complete() - .delete() - .queueAfter(10, TimeUnit.SECONDS); - }).start(); - } - - private void alertMsg(String msg) { - new TechEmbedBuilder() - .text(msg) - .queue(getJDA().getUserById("619084935655063552")); - new TechEmbedBuilder() - .text(msg) - .queue(getJDA().getUserById("319429800009662468")); - } - - @Override - public String getName() { - return "Verification"; - } - - @Override - public Requirement[] getRequirements() { - return new Requirement[]{ - new Requirement(VERIFICATION_CHANNEL, 1, "Missing Verification Channel (#verification)") - }; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/WordBlacklistModule.java b/src/main/java/me/TechsCode/TechDiscordBot/module/modules/WordBlacklistModule.java deleted file mode 100644 index 258546dc..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/module/modules/WordBlacklistModule.java +++ /dev/null @@ -1,154 +0,0 @@ -package me.TechsCode.TechDiscordBot.module.modules; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.module.Module; -import me.TechsCode.TechDiscordBot.objects.DefinedQuery; -import me.TechsCode.TechDiscordBot.objects.Query; -import me.TechsCode.TechDiscordBot.objects.Requirement; -import me.TechsCode.TechDiscordBot.util.TechEmbedBuilder; -import net.dv8tion.jda.api.entities.Category; -import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; -import net.dv8tion.jda.api.events.message.guild.GuildMessageUpdateEvent; -import net.dv8tion.jda.api.hooks.SubscribeEvent; - -import java.awt.*; -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class WordBlacklistModule extends Module { - - private final DefinedQuery IGNORED_CATEGORIES = new DefinedQuery() { - @Override - protected Query newQuery() { - return bot.getCategories("\uD83D\uDCC1 | Archives", "\uD83D\uDCD1 | Staff Logs", "Staff Discussions", "⚖ | Leadership-Discussions"); //Category for Official Use - //return bot.getCategories("\uD83D\uDCAC | Community Talk", "\uD83D\uDCAC | General Discussions", "\uD83D\uDCE6︱Free Plugin Support", "\uD83D\uDCE6︱Paid Plugin Support", "⚖ | Leadership-Discussions", "Staff Discussions"); //Category for Testuse - } - }; - - private final List BLACKLISTED_WORDS = new ArrayList<>(); - private final String URL = "https://raw.githubusercontent.com/TechsCode-Team/TechBot-Whitelists/main/wordBlacklist"; - - public WordBlacklistModule(TechDiscordBot bot) { - super(bot); - } - - @Override - public void onEnable() { - new Thread(() -> { - while (true) { - getBlacklist(); - - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(10)); - } catch (Exception ignored) { } - } - }).start(); - } - - @Override - public void onDisable() { } - - public String getName() { - return "WordBlacklistModule"; - } - - @SubscribeEvent - public void onMessage(GuildMessageReceivedEvent e) { - if (e.getMember() == null || e.getAuthor().isBot() || IGNORED_CATEGORIES.query().stream().anyMatch(c -> c.getId().equals(e.getChannel().getParent().getId()))) return; - - if (runMatcher(e.getMessage().getContentRaw().toLowerCase())){ - e.getMessage().delete().queue(); - new TechEmbedBuilder("Blocked Word(s)") - .color(Color.RED) - .text("Your message contained a world which is in our blacklist.\n\nIf you think this is a mistake, take a look at our [**word blacklist**](" + URL + ").") - .sendTemporary(e.getChannel(), 10, TimeUnit.SECONDS); - } - } - - @SubscribeEvent - public void onMessageUpdate(GuildMessageUpdateEvent e) { - if (e.getMember() == null || e.getAuthor().isBot() || IGNORED_CATEGORIES.query().stream().anyMatch(c -> c.getId().equals(e.getChannel().getParent().getId()))) return; - - if (runMatcher(e.getMessage().getContentRaw().toLowerCase())){ - e.getMessage().delete().queue(); - new TechEmbedBuilder("Blocked Word(s)") - .color(Color.RED) - .text("Your message contained a world which is in our blacklist.\n\nIf you think this is a mistake, take a look at our [**word blacklist**](" + URL + ").") - .sendTemporary(e.getChannel(), 10, TimeUnit.SECONDS); - } - } - - public boolean runMatcher(String message){ - AtomicBoolean blockMessage = new AtomicBoolean(false); - - for (String regex : BLACKLISTED_WORDS) { - Matcher matcher = Pattern.compile(regex, Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL).matcher(message); - boolean matches = matcher.matches(); - boolean find = matcher.find(); - - if (matches) { - blockMessage.set(true); - } - if (find) { - blockMessage.set(true); - } - if (blockMessage.get()){ - break; - } - } - return blockMessage.get(); - } - - private void getBlacklist() { - try { - URL url = new URL(URL); - - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("GET"); - - int status = con.getResponseCode(); - - if (status == 200) { - BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); - String inputLine; - - BLACKLISTED_WORDS.clear(); - while ((inputLine = in.readLine()) != null) { - String word = inputLine.trim().toLowerCase(); - - String[] letters = word.split(""); - StringBuilder regex = new StringBuilder(); - regex.append("\\b("); - for (String letter : letters) { - regex.append(letter).append("+(\\W|\\d|_)*"); - } - regex.append(")"); - - BLACKLISTED_WORDS.add(regex.toString()); - } - - in.close(); - } else { - TechDiscordBot.log("ERROR", "Failed to fetch the black listed words."); - } - - con.disconnect(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public Requirement[] getRequirements() { - return new Requirement[] { - new Requirement(IGNORED_CATEGORIES, IGNORED_CATEGORIES.query().amount(), "Could not find all of the ignored category channels.") - }; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/ApplyModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/ApplyModule.java new file mode 100644 index 00000000..45e57f52 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/ApplyModule.java @@ -0,0 +1,224 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.debug.Debugger; +import com.greazi.discordbotfoundation.settings.SimpleSettings; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.actions.buttons.ApplyButton; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlApplication; +import me.techscode.techdiscordbot.model.enums.Application; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CompletableFuture; + +public class ApplyModule { + + private static final String APPLY_CHANNEL_ID = Settings.Modules.Apply.channel; + + public static void embed() { + + if (!Settings.Modules.Apply.enabled) return; + + // The Verification text channel + final TextChannel channel = Objects.requireNonNull(TechDiscordBot.getJDA().getGuildById(SimpleSettings.Bot.MainGuild())).getTextChannelById(APPLY_CHANNEL_ID); + + + // Create the verification embed + final SimpleEmbedBuilder embed = new SimpleEmbedBuilder("Applications | How it works") + .text( + "Welcome to the applications channel in here you can create your application to be a staff member on the server.", + "", + "**Open positions**", + "- Supporter - *Help people with their problems*", + "- Developer - *Help our development team to develop our plugins*", + "- Marketing - *Be creative and discuss new marketing ideas make drawings and much more*", + "- Community Helper - *Help us maintain our Translations and Wiki pages*", + "", + "**How to create a application?**", + "Click on the button below to create a application. After that there will be a application created for you." + ) + .color(new Color(81, 153, 226)); + + // Debug message to see what the application channel is + assert channel != null; + Debugger.debug("Applications", "channel name == " + channel.getName() + " channel id == " + channel.getId()); + + // Send the embed with the buttons to the verification channel + channel.sendMessageEmbeds(embed.build()) + .setActionRow( + new ApplyButton.Button().build() + ).queue(); + } + + public static CompletableFuture applicationCreate(@NotNull Member member, Guild guild) { + + // Permissions list for the applications channel + final List allowedPermissions = new ArrayList<>( + Arrays.asList( + Permission.VIEW_CHANNEL, + Permission.MESSAGE_SEND, + Permission.MESSAGE_HISTORY, + Permission.MESSAGE_ATTACH_FILES, + Permission.MESSAGE_EMBED_LINKS, + Permission.MESSAGE_ADD_REACTION, + Permission.MANAGE_EMOJIS_AND_STICKERS + ) + ); + + // Get the members name if the members name can't be gathered it will use the user's ID + final String memberName; + if (Objects.equals(member.getNickname(), "") || member.getNickname() == null) { + if (member.getEffectiveName().equals("")) { + memberName = member.getUser().getId(); + } else { + member.getEffectiveName(); + memberName = member.getEffectiveName(); + } + } else { + memberName = member.getNickname(); + } + + // Get some settings from the settings file + final Category category = guild.getCategoryById(Settings.Modules.Apply.category); + final long supportRole = Settings.Roles.support; + final long developmentRole = Settings.Roles.development; + final long leadershipRole = Settings.Roles.leadership; + + CompletableFuture future = new CompletableFuture<>(); + + // Create the application channel for the member + guild.createTextChannel("application-" + memberName, category) + .addPermissionOverride(guild.getPublicRole(), null, allowedPermissions) + // Add staff permissions + .addRolePermissionOverride(supportRole, allowedPermissions, null) + .addRolePermissionOverride(developmentRole, allowedPermissions, null) + .addRolePermissionOverride(leadershipRole, allowedPermissions, null) + // Add member permissions + .addMemberPermissionOverride(member.getIdLong(), allowedPermissions, null) + .queue( + (channel) -> { + channel.sendMessageEmbeds(new SimpleEmbedBuilder("Application creation (1/3)") + .text( + "**Hi there " + member.getAsMention() + ",**", + "", + "Thank you for your interest in one of our open roles. To complete your application, you will be asked a few questions. This is divided into two parts: general questions in Part 1 and questions in Part 2 based on the direction you want to take.", + "", + "The questions we'd like answered are listed below. The button displays input fields where you can answer the questions. You can close the field at any time, and all progress is saved.", + "***NOTE:** After 15 minutes, the input field will no longer function.*" + ) + .field("What is your name and age?", "Please enter your name and age.", false) + .field("What is your timezone?", "Please enter your timezone.", false) + .field("Available time per week?", "Please enter your available time per week.", false) + .field("Why do you want to join the team?", "Please enter your reason for wanting to join the team.", false) + .field("What are your pro's and con's?", "Please enter your pro's and con's.", false) + .build() + ).addActionRow(new ApplyButton.GeneralQuestionButton(member).build()).queue(); + new SqlApplication(Database.MEMBERSTable.getFromDiscordId(member.getIdLong()).get(0).getId(), channel.getIdLong(), channel.getTimeCreated().toEpochSecond(), null).save(); + + future.complete(channel); + }, + + (error) -> { + guild.createTextChannel("application-" + member.getId(), category) + .addPermissionOverride(guild.getPublicRole(), null, allowedPermissions) + // Add staff permissions + .addRolePermissionOverride(supportRole, allowedPermissions, null) + .addRolePermissionOverride(developmentRole, allowedPermissions, null) + .addRolePermissionOverride(leadershipRole, allowedPermissions, null) + // Add member permissions + .addMemberPermissionOverride(member.getIdLong(), allowedPermissions, null) + .queue(channel -> { + channel.sendMessageEmbeds(new SimpleEmbedBuilder("Application creation (1/3)") + .text( + "**Hi there " + member.getAsMention() + ",**", + "", + "Thank you for your interest in one of our open roles. To complete your application, you will be asked a few questions. This is divided into two parts: general questions in Part 1 and questions in Part 2 based on the direction you want to take.", + "", + "The questions we'd like answered are listed below. The button displays input fields where you can answer the questions. You can close the field at any time, and all progress is saved.", + "***NOTE:** After 15 minutes, the input field will no longer function.*" + ) + .field("What is your name and age?", "Please enter your name and age.", false) + .field("What is your timezone?", "Please enter your timezone.", false) + .field("Available time per week?", "Please enter your available time per week.", false) + .field("Why do you want to join the team?", "Please enter your reason for wanting to join the team.", false) + .field("What are your pro's and con's?", "Please enter your pro's and con's.", false) + .build() + ).addActionRow(new ApplyButton.GeneralQuestionButton(member).build()).queue(); + new SqlApplication(Database.MEMBERSTable.getFromDiscordId(member.getIdLong()).get(0).getId(), channel.getIdLong(), channel.getTimeCreated().toEpochSecond(), null).save(); + + future.complete(channel); + }); + }); + + return future; + } + + public static void finishApplicationCreation(@NotNull TextChannel channel, Member member) { + SqlApplication sqlApplication = Database.APPLICATIONSTable.get(channel.getIdLong()).get(0); + + Application.Position position = sqlApplication.getCategory(); + + channel.sendMessageEmbeds(new SimpleEmbedBuilder("Apply - " + member.getUser().getAsTag()) + .text( + "Thank you for creating a Application.", + "We will discuss your application and get back to you as soon as possible." + ) + .field("Position", position.getEmoji().getFormatted() + " " + position.getName(), true) + .success().build()).queue(); + + channel.getManager().setTopic( "This Application has been created by " + member.getAsMention() + "\n" + + " **- Created at:** \n" + + " **- Position:** " + position.getEmoji().getFormatted() + " " + position.getName() + "\n" ).queue(); + } + + public static void applicationClose(@NotNull TextChannel applicationChannel, long unixTime) { + applicationChannel.sendMessageEmbeds(new SimpleEmbedBuilder("Apply - " + applicationChannel.getName()) + .text("This Application will be closed in 30 seconds.", + "**Time closed:** ") + .error().build()).queue(); + + // TODO: Add transcript system here + + new Thread(() -> { + try { + Thread.sleep(30000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + applicationChannel.delete().queue(); + Database.APPLICATIONSTable.remove(applicationChannel.getIdLong()); + }).start(); + } + + public static void applicationClose(@NotNull TextChannel applicationChannel, long unixTime, String reason) { + applicationChannel.sendMessageEmbeds(new SimpleEmbedBuilder("Apply - " + applicationChannel.getName()) + .text("This Application will be closed in 30 seconds.", + "**Time closed:** ", + "**Reason:** " + reason) + .error().build()).queue(); + + // TODO: Add transcript system here + + new Thread(() -> { + try { + Thread.sleep(30000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + applicationChannel.delete().queue(); + Database.APPLICATIONSTable.remove(applicationChannel.getIdLong()); + }).start(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/BotMentionModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/BotMentionModule.java new file mode 100644 index 00000000..0fd26655 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/BotMentionModule.java @@ -0,0 +1,30 @@ +package me.techscode.techdiscordbot.modules; + +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.hooks.SubscribeEvent; + +/** + * A module that listens for mentions of the bot. + */ +public class BotMentionModule extends ListenerAdapter { + + /** + * Listens for mentions of the bot. + * @param event message received event + */ + @SubscribeEvent + public void onBotMention(MessageReceivedEvent event) { + + // Check if the message contains a mention of the bot + if (event.getMessage().getContentRaw().startsWith("<@" + event.getJDA().getSelfUser().getId() + ">")) { + + // Send a hello message back to the user + event.getChannel().sendMessage("Hello " + event.getMember().getAsMention() + ", I'm TechDiscordBot!").queue(); + + // Add an emoji to the message + event.getMessage().addReaction(Emoji.fromUnicode("👀")).queue(); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/ChatLogModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/ChatLogModule.java new file mode 100644 index 00000000..4c9d8bdb --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/ChatLogModule.java @@ -0,0 +1,47 @@ +package me.techscode.techdiscordbot.modules; + +import me.techscode.techdiscordbot.model.Logs; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.events.message.MessageDeleteEvent; +import net.dv8tion.jda.api.events.message.MessageUpdateEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +import java.util.HashMap; + +/* + * MessageId | ChannelId | UserId | BLOB | LogDate + */ + + +public class ChatLogModule extends ListenerAdapter { + + // A HashMap with all messages send when the bot is started + private final HashMap cachedMessages = new HashMap<>(); + + /** + * Listens for messages that are deleted + * + * @param event MessageDeleteEvent + */ + @Override + public void onMessageDelete(final MessageDeleteEvent event) { + final String messageId = event.getMessageId(); + final Message message = event.getChannel().retrieveMessageById(messageId).complete(); + + Logs.ChatLogs.log(message); + } + + /** + * Listens for messages that are edited + * + * @param event MessageUpdateEvent + */ + @Override + public void onMessageUpdate(final MessageUpdateEvent event) { + final String messageId = event.getMessageId(); + final Message message = event.getChannel().retrieveMessageById(messageId).complete(); + final Message message2 = event.getMessage(); + + Logs.ChatLogs.log(message); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/MemberJoinModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/MemberJoinModule.java new file mode 100644 index 00000000..33adbc70 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/MemberJoinModule.java @@ -0,0 +1,39 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import com.greazi.discordbotfoundation.utils.color.ConsoleColor; +import me.techscode.techdiscordbot.database.entities.SqlMember; +import me.techscode.techdiscordbot.model.Logs; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.events.guild.member.GuildMemberJoinEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.hooks.SubscribeEvent; +import net.dv8tion.jda.api.utils.TimeUtil; + +public class MemberJoinModule extends ListenerAdapter { + + @SubscribeEvent + public static void onMemberJoin(final GuildMemberJoinEvent event) { + final Thread thread = new Thread(() -> { + + final Member member = event.getMember(); + + final String name = member.getEffectiveName(); + final long id = member.getIdLong(); + + Common.log(ConsoleColor.CYAN + member.getUser().getAsTag() + ConsoleColor.RESET + " has joined the server"); + + new SqlMember(id).save(); + + Logs.ServerLogs.log(new SimpleEmbedBuilder("Member joined!") + .field("Name:", name, true) + .field("ID:", String.valueOf(id), true) + .field("Account created:", TimeUtil.getDateTimeString(member.getTimeCreated()), true) + .thumbnail(member.getUser().getAvatarUrl()) + .success()); + }); + thread.setName("MemberJoinModule-" + event.getUser().getId()); + thread.start(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/MemberLeaveModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/MemberLeaveModule.java new file mode 100644 index 00000000..028d3cc2 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/MemberLeaveModule.java @@ -0,0 +1,36 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import com.greazi.discordbotfoundation.utils.color.ConsoleColor; +import me.techscode.techdiscordbot.model.Logs; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.hooks.SubscribeEvent; +import net.dv8tion.jda.api.utils.TimeUtil; + +public class MemberLeaveModule extends ListenerAdapter { + + @SubscribeEvent + public static void onMemberLeave(final GuildMemberRemoveEvent event) { + final Thread thread = new Thread(() -> { + + final User user = event.getUser(); + + final String name = user.getName(); + final long id = user.getIdLong(); + + Common.log(ConsoleColor.CYAN + user.getAsTag() + ConsoleColor.RESET + " has left the server"); + + Logs.ServerLogs.log(new SimpleEmbedBuilder("Member left!") + .field("Name:", name, true) + .field("ID:", String.valueOf(id), true) + .field("Account created:", TimeUtil.getDateTimeString(user.getTimeCreated()), true) + .thumbnail(user.getAvatarUrl()) + .error()); + }); + thread.setName("MemberLeaveModule-" + event.getUser().getId()); + thread.start(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/MessageReceive.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/MessageReceive.java new file mode 100644 index 00000000..a4406995 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/MessageReceive.java @@ -0,0 +1,433 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.debug.Debugger; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import com.greazi.discordbotfoundation.utils.color.ConsoleColor; +import me.techscode.techdiscordbot.actions.buttons.DeleteButton; +import me.techscode.techdiscordbot.model.Pastebin; +import me.techscode.techdiscordbot.settings.Settings; +import me.techscode.techdiscordbot.utils.ProjectUtil; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.concrete.ThreadChannel; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.hooks.SubscribeEvent; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.time.LocalDate; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class MessageReceive extends ListenerAdapter { + + @SubscribeEvent + public void onMessageReceived(@NotNull MessageReceivedEvent event) { + + this.log(event); + + this.bugReport(event); + + this.suggestion(event); + + //this.vacationGreazi(event); + + this.staffEmbed(event); + + this.messageAsBot(event); + + this.pastebinCheck(event); + + this.fileReceived(event); + + this.support(event); + } + + private void support(@NotNull MessageReceivedEvent event) { + long categoryId = event.getGuildChannel().getIdLong(); + if (categoryId == 457963200567181323L || categoryId == 696130901293400064L) { + String message = event.getMessage().getContentRaw().toLowerCase(); + + // Regular expressions for plugin abbreviations, full names, and keywords + String pluginAbbreviations = "UC|UP|UPun|UE|UR|UMotd|US|UBoards|IShops|IV|ISpwaners"; + String fullNames = "Ultra Customizer|Ultra Punishments|Ultra Permissions|Ultra Economy|Ultra Regions|Ultra Motd|Ultra Scoreboards|Insane Shops|Insane Vaults|Insane Spawners"; + String supportKeywords = "help|support|assistance|assist|need"; + + // Combine all expressions into one pattern + String combinedPattern = String.format("(%s)|(%s)|(%s)", pluginAbbreviations, fullNames, supportKeywords); + Pattern pattern = Pattern.compile(combinedPattern, Pattern.CASE_INSENSITIVE); + + // Create a Matcher to find matches in the message + Matcher matcher = pattern.matcher(message); + + // Check if any plugin abbreviation, full name, or support keyword is found in the message + if (matcher.matches()) { + // Send a reply asking the user to verify their purchase + event.getChannel().asTextChannel().sendMessageEmbeds(new SimpleEmbedBuilder() + .text("Hello, " + event.getMember().getAsMention() + "! I've detected that you might be trying to get help in this channel! Please verify in <#907349490556616745> in order to get help, thanks!\n\n*If you are not trying to get help, you can delete this message by reacting to it!*") + .error().build() + ).addActionRow(new DeleteButton(event.getMember().getId()).build()).queue(); + } + } + } + + /** + * Chat log to the console + * @param event MessageReceivedEvent + */ + private void log(@NotNull MessageReceivedEvent event) { + if (event.getAuthor().isBot()) return; + + String primary = ""; + + try { + primary = event.getGuildChannel().asStandardGuildChannel().getParentCategory().getName(); + } catch (Exception e) { + primary = event.getGuildChannel().asThreadChannel().getParentChannel().getName(); + } + Common.logNoPrefix(ConsoleColor.PURPLE + "[" + (primary != null ? primary : "") + "/" + event.getChannel().getName() + "] " + ConsoleColor.CYAN + event.getAuthor().getName() + ConsoleColor.WHITE + ": " + event.getMessage().getContentRaw()); + } + + private void pastebinCheck(@NotNull MessageReceivedEvent event) { + String message = event.getMessage().getContentRaw().toLowerCase(); + + if (message.contains("send in") && message.contains("pastebin")) { + event.getChannel().asTextChannel().sendMessage("https://paste.techscode.com/").queue(); + } + + + } + + /** + * Staff embed system + * @param event MessageReceivedEvent + */ + private void staffEmbed(@NotNull MessageReceivedEvent event) { + + // Get the message + String message = event.getMessage().getContentRaw(); + + // Check if the message starts with the "^ " prefix + if (message.startsWith("^ ")) { + + // Check if the member has the staff role + if (event.getMember().getRoles().contains(event.getGuild().getRoleById(Settings.Roles.staff))) { + + // Delete the original message + event.getMessage().delete().queue(); + + String text = message.substring(2); + String[] arguments = text.split("\\^"); + + if (arguments.length != 2 && arguments.length != 3 && arguments.length != 4) { + new SimpleEmbedBuilder("Invalid Arguments") + .text( + "Example usages:", + "- `^ ^ <text> ^`", + "- `^ <title> ^ <text> ^ <color> ^`", + "- `^ <title> ^ <text> ^ <thumbnail> ^`", + "- `^ <title> ^ <text> ^ <color> ^ <thumbnail> ^`", + "", + "Example: ^ Hello ^ This is a test ^ #ff0000 ^ https://www.google.com/someimage.png" + + ) + .error().sendTemporary(event.getChannel().asTextChannel(), 10); + return; + } + + if (arguments.length == 4) { + new SimpleEmbedBuilder(arguments[0]) + .footer("Posted by " + event.getAuthor().getName()) + .text(arguments[1]) + .color(Color.decode(arguments[2].trim())) + .thumbnail(arguments[3]) + .queue(event.getChannel().asTextChannel()); + } + + if (arguments.length == 3) { + if (arguments[2].trim().startsWith("#")) { + new SimpleEmbedBuilder(arguments[0]) + .footer("Posted by " + event.getAuthor().getName()) + .text(arguments[1]) + .color(Color.decode(arguments[2].trim())) + .queue(event.getChannel().asTextChannel()); + } else { + new SimpleEmbedBuilder(arguments[0]) + .footer("Posted by " + event.getAuthor().getName()) + .text(arguments[1]) + .thumbnail(arguments[2]) + .queue(event.getChannel().asTextChannel()); + } + + } else { + new SimpleEmbedBuilder(arguments[0]) + .footer("Posted by " + event.getAuthor().getName()) + .text(arguments[1]) + .queue(event.getChannel().asTextChannel()); + } + } + } + } + + /** + * Send a message as the bot + * @param event MessageReceivedEvent + */ + private void messageAsBot(@NotNull MessageReceivedEvent event) { + // Get the message + String message = event.getMessage().getContentRaw(); + if (message.startsWith("^^ ") && message.endsWith(" ^^")) { + + // Check if the member has the staff role + if (event.getMember().getRoles().contains(event.getGuild().getRoleById(Settings.Roles.staff))) { + event.getMessage().delete().queue(); + + String text = message.substring(3, message.length() - 3); + event.getChannel().sendMessage(text).queue(); + return; + } + } + } + + /** + * Reads the text from images. + * @param event MessageReceivedEvent + */ + private void fileReceived(@NotNull MessageReceivedEvent event) { + // Check if the message contains a file and adds it to a pastebin. + event.getMessage().getAttachments().forEach(attachment -> { + + if (attachment.isImage()) { + /*// Check for unused channels + switch (event.getChannel().getId()) { + case "430176899445161984", "859589285480235019", "608486215439613962", "764594873860227143", "828097631593955348", "907349490556616745", "837679014268895292", "608450789110710275", "738835343788474368", "346344529651040268", "1089093673771356170", "896839416176345110", "998167763791138816", "1086074047185571972", "522049992131608576", "1089865392371007520" -> { + return; + } + } + + event.getMessage().addReaction(Emoji.fromFormatted("👀")).queue(); + + if (attachment.getFileExtension() == null) return; + switch (attachment.getFileExtension()) { + case "png", "jpg", "jpeg" -> { + + String content; + + try { + InputStream imageStream = attachment.getProxy().download().join(); + + File file = ProjectUtil.GrayScale(imageStream); + + imageStream.close(); + + content = ProjectUtil.getTextFromImage(file); + } catch (IOException e) { + throw new RuntimeException(e); + } + + event.getMessage().reply("```" + content + "```").queue(); + } + }*/ + } else if (attachment.isVideo() && Settings.Modules.MessageReceive.image) { + // Check for unused channels + switch (event.getChannel().getId()) { + case "430176899445161984", "859589285480235019", "608486215439613962", "764594873860227143", "828097631593955348", "907349490556616745", "837679014268895292", "608450789110710275", "738835343788474368", "346344529651040268", "1089093673771356170", "896839416176345110", "998167763791138816", "1086074047185571972", "522049992131608576L" -> { + return; + } + } + + event.getMessage().addReaction(Emoji.fromFormatted("👀")).queue(); + } else if (Settings.Modules.MessageReceive.pastebin) { + + if (attachment.getFileExtension() == null) return; + switch (attachment.getFileExtension()) { + case "zip", "rar", "7z", "tar", "gz", "jar", "mp3", "mp4", "ogg" -> { + return; + } + } + + CompletableFuture<InputStream> future = attachment.getProxy().download(); + InputStream stream = null; + try { + stream = future.get(); + } catch (InterruptedException | ExecutionException e) { + Common.throwError(e, "Failed to download attachment from message"); + } + + try { + String message = new String(stream.readAllBytes()); + + event.getMessage().replyEmbeds(new SimpleEmbedBuilder("Pastebin") + .text( + "We would like to remind you that we have a pastebin for any message that is to big for Discord.", + "", + "We have been so kind to upload your message for you, you can find it here: **" + Pastebin.post(message, false) + "." + attachment.getFileExtension() + "**" + ) + .build() + ).queue(); + + stream.close(); + + } catch (IOException e) { + event.getMessage().replyEmbeds(new SimpleEmbedBuilder("Pastebin") + .text( + "Hi there,", + "We would like to remind you that we have a pastebin for any message that is to big for Discord.", + "You can find it here: https://paste.techscode.com/", + "Please upload your message/file there and send the link in this channel." + ) + .build() + ).queue(); + throw new RuntimeException(e); + } + } + }); + } + + /** + * Vacation embed when Greazi is on vacation + * @param event MessageReceivedEvent + */ + private void vacationGreazi(MessageReceivedEvent event) { + // Get the current date + LocalDate currentDate = LocalDate.now(); + + // Define the start and end dates for the range + LocalDate startDate = LocalDate.of(currentDate.getYear(), 8, 1); + LocalDate endDate = LocalDate.of(currentDate.getYear(), 8, 27); + + // Check if the current date is within the range + if (currentDate.isAfter(startDate) && currentDate.isBefore(endDate) || currentDate.isEqual(startDate) || currentDate.isEqual(endDate)) { + List<Member> mentionedMembers = event.getMessage().getMentions().getMembers(); + for (Member mentionMember : mentionedMembers) { + if (mentionMember.getUser().isBot()) continue; + if (mentionMember.getUser().getId().equals(event.getAuthor().getId())) continue; + + + + if (mentionMember.getUser().getId().equals("619084935655063552")) { + event.getChannel().sendMessageEmbeds( + new SimpleEmbedBuilder("Keep in mind!") + .text( + "Hi 👋🏻, I am currently on vacation until <t:1693548000:D>.", + "", + "If there is something urgent, please contact a staff member, they will be able to help you out.", + "When something is important for me (Greazi) to see than you can send me a DM. Once I am back I will read all my DM's.", + "", + "Thank you for your understanding!" + ) + .color(new Color(0, 255, 206)) + .thumbnail("https://www.greazi.com/wp-content/uploads/2022/09/Greazi-758x1024-1.png") + .build() + ).queue(); + } + } + } + } + + private void bugReport(@NotNull MessageReceivedEvent event) { + + if (event.getChannelType().isThread()) { + ThreadChannel threadChannel = event.getChannel().asThreadChannel(); + if (threadChannel.getParentChannel().getName().equals("bug-reports") && threadChannel.getMessageCount() < 2) { + String message = event.getMessage().getContentRaw(); + + if (!message.contains("Server Info") || !message.contains("Plugin Info") || !message.contains("Describe the bug") || !message.contains("To Reproduce") || !message.contains("Plugin List")) { + event.getChannel().asThreadChannel().sendMessage( + "Hello 👋, and thank you for creating this bug report " + event.getAuthor().getAsMention() + "! We're glad to see you here, but we'll definitely need a little more information from you before we can get your bug report solved.\n" + + "\n" + + "We need as much information as possible regarding your server and problem, therefore we've created a template for you to fill out. We do not accept files, therefore please submit your error(s) and logs in a pastebin.\n" + + "\n" + + "**Template:**\n" + + "```" + + "**Server Info (please complete the following information):**\n" + + " - Server Type: [e.g. Paper]\n" + + " - Server Version: [e.g. 1.16.5]\n" + + " - Java Version [e.g. 17.0.1]\n" + + " - Online-Mode: [e.g. True/False]\n" + + " - BungeeCord: [e.g. True/False]\n" + + " - Server Logs: [e.g. https://paste.techscode.com]\n" + + "\n" + + "**Plugin Info (please complete the following information):**\n" + + " - Version: [e.g. 1.0.0]\n" + + " - MySQL: [e.g. Yes/No]\n" + + "\n" + + "**Describe the bug**\n" + + "A clear and concise description of what the bug is.\n" + + "\n" + + "**To Reproduce**\n" + + "Steps to reproduce the behavior:\n" + + "1. Go to '...'\n" + + "2. Click on '....'\n" + + "3. Scroll down to '....'\n" + + "4. See error\n" + + "\n" + + "**Expected behavior**\n" + + "A clear and concise description of what you expected to happen.\n" + + "\n" + + "**Screenshots/Videos**\n" + + "If applicable, add screenshots or a video link to help explain your problem.\n" + + "\n" + + "**Plugin List (please provide us with the full list of your plugins)**\n" + + "\n" + + "**Additional context**\n" + + "Add any other context about the problem here.```\n" + + "\n" + + "**Pastebin:**\n" + + "https://paste.techscode.com/" + ).queue(); + } + } + } + } + + private void suggestion(@NotNull MessageReceivedEvent event) { + if (event.getChannelType().isThread()) { + ThreadChannel threadChannel = event.getChannel().asThreadChannel(); + if (threadChannel.getParentChannel().getName().equals("suggestions") || threadChannel.getParentChannel().getName().equals("priority-suggestions")) { + if (threadChannel.getMessageCount() < 2) { + String message = event.getMessage().getContentRaw(); + + if (!message.contains("Suggestion Description") || !message.contains("Reason for your suggestion") || !message.contains("help others") || !message.contains("Additional Context")) { + event.getChannel().asThreadChannel().sendMessage( + "Hello 👋, and thank you for sharing your suggestion " + event.getAuthor().getAsMention() + "! We appreciate your input and would like to gather more details about your suggestion to better understand and evaluate it.\n" + + "\n" + + "To ensure we can consider your suggestion effectively, please follow the template provided below:\n" + + "\n" + + "**Template:**\n" + + "```" + + "**Suggestion Description:**\n" + + "A clear and concise description of your suggestion.\n" + + "\n" + + "**Reason for your suggestion?:**\n" + + "Explain why you believe this suggestion would be beneficial or address a specific issue.\n" + + "\n" + + "**How can this help others?:**\n" + + "Explain why you believe this suggestion would be beneficial or address a specific issue.\n" + + "\n" + + "**Implementation Details (if any):**\n" + + "If you have any technical or implementation details in mind, please share them here.\n" + + "\n" + + "**Additional Context:**\n" + + "Any extra information or context that can help us understand your suggestion better.\n" + + "```\n" + + "\n" + + "Your input is valuable to us, and we'll review your suggestion carefully. Thank you for taking the time to contribute to our project!" + ).queue(); + } + } + } + } + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/PluginLabModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/PluginLabModule.java new file mode 100644 index 00000000..275d9b63 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/PluginLabModule.java @@ -0,0 +1,20 @@ +package me.techscode.techdiscordbot.modules; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +/** + * TODO: Fix all the comment and finish this file! + */ +public class PluginLabModule extends ListenerAdapter { + + /** + * Listens for mentions of the bot. + * @param event message received event + */ + @Override + public void onMessageReceived(MessageReceivedEvent event) { + + // TODO: Finish the code + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/PreorderModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/PreorderModule.java new file mode 100644 index 00000000..fb56f509 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/PreorderModule.java @@ -0,0 +1,80 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.debug.Debugger; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.TranscriptDatabase; +import me.techscode.techdiscordbot.database.entities.SqlPreorder; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.UserSnowflake; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; + +import java.awt.*; +import java.util.List; +import java.util.stream.Collectors; + +public class PreorderModule { + + /*public static void CheckPreorders() { + if (Settings.Modules.Preorder.enabled) { + int preorders = 0; + int newAdded = 0; + + for (final SqlPreorder sqlPreorder : TranscriptDatabase.PREORDERS.getAll()) { + final long discordId = sqlPreorder.getDiscordId(); + final Member member = TechDiscordBot.getMainGuild().getMember(UserSnowflake.fromId(discordId)); + + if (member == null) { + Debugger.debug("PreorderModule", "Member with ID " + discordId + " is null."); + preorders++; + continue; + } + + final List<Role> roles = member.getRoles(); + final List<Long> roleIds = roles.stream().map(Role::getIdLong).collect(Collectors.toList()); + + if (roleIds.contains(Settings.Roles.preorder) && sqlPreorder.getTransactionId().equalsIgnoreCase("none")) { + Debugger.debug("PreorderModule", "Member with ID " + discordId + " has the preorder role but no transaction ID. Removing role."); + SimpleRoles.removeRole(member, Settings.Roles.Patreon.patreon); + preorders++; + } else if (!sqlPreorder.getTransactionId().equalsIgnoreCase("none")) { + if (!member.getRoles().contains(SimpleRoles.getRoleById(member.getGuild(), Settings.Roles.preorder))) { + preorders++; + newAdded++; + + SimpleRoles.addRole(member, Settings.Roles.preorder); + + Debugger.debug("PreorderModule", "Member with ID " + discordId + " has a transaction ID but no preorder role. Adding role."); + final TextChannel preorderChannel = TechDiscordBot.getJDA().getTextChannelById(Settings.Modules.Preorder.channel); + + assert preorderChannel != null; + preorderChannel.sendMessageEmbeds(new SimpleEmbedBuilder("Insane Vaults Preorder") + .text( + "**" + member.getAsMention() + " thank you for pre-ordering Insane Vaults!**", + "", + "Your pre-order has been verified and you have been given the " + SimpleRoles.getRoleById(member.getGuild(), Settings.Roles.preorder).getAsMention() + " role.", + "", + "You can now access <#1058612057576054864> for your support questions.", + "To download the latest build of Insane Vaults go to the preorder page **[HERE](https://preorder.insanevaults.com/)**" + ) + .color(Color.getColor("#e74c3c")) + .thumbnail("https://cloud.techscode.com/s/J6SaqeQRrErQwft/preview") + .build() + ).queue(); + Common.log("Added Preorder role to " + member.getUser().getAsTag() + " and sent them a message."); + + } else { + Debugger.debug("PreorderModule", "Member with ID " + discordId + " has a transaction ID and the preorder role. Skipping."); + member.getGuild().addRoleToMember(member, SimpleRoles.getRoleById(member.getGuild(), Settings.Roles.preorder)).queue(); + preorders++; + } + } + } + Common.log("Preorder system finished checking preorders. " + preorders + " preorders found and " + newAdded + " new preorders added."); + } + }*/ +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/PrivateMessageReceiveModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/PrivateMessageReceiveModule.java new file mode 100644 index 00000000..a5082cc4 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/PrivateMessageReceiveModule.java @@ -0,0 +1,26 @@ +package me.techscode.techdiscordbot.modules; + +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.channel.ChannelType; +import net.dv8tion.jda.api.entities.emoji.Emoji; +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.hooks.SubscribeEvent; + +/** + * A temporary way adding event listeners + * this will be finished / updated later + */ +public class PrivateMessageReceiveModule extends ListenerAdapter { + + @SubscribeEvent + public void onPrivateMessageReceive(MessageReceivedEvent event) { + Message message = event.getMessage(); + + if (message.getChannelType() != ChannelType.PRIVATE) return; + if (event.getAuthor().isBot()) return; + + message.addReaction(Emoji.fromUnicode("👀")).queue(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/RolesModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/RolesModule.java new file mode 100644 index 00000000..b4603c6f --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/RolesModule.java @@ -0,0 +1,112 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.utils.SimpleRoles; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import com.greazi.discordbotfoundation.utils.color.ConsoleColor; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.SqlMember; +import me.techscode.techdiscordbot.database.entities.SqlPatreon; +import me.techscode.techdiscordbot.model.Logs; +import me.techscode.techdiscordbot.model.enums.Patreon; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleAddEvent; +import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.hooks.SubscribeEvent; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * TODO: Fix all the comment and finish this file! + */ +public class RolesModule extends ListenerAdapter { + + /** + * Listen for role add event + * @param event GuildMemberRoleAddEvent + */ + @SubscribeEvent + public void onRoleAdd(@NotNull GuildMemberRoleAddEvent event) { + if (event.getGuild() == TechDiscordBot.getMainGuild()) { + log(event.getMember(), true, event.getRoles()); + } + + SqlMember sqlMember = Database.MEMBERSTable.getFromDiscordId(event.getMember().getIdLong()).get(0); + + for (Role role : event.getRoles()) { + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.patreon)) { + if (Database.PATREONTable.getByDiscordId(event.getMember().getIdLong()).isEmpty()) { + Database.PATREONTable.add(new SqlPatreon(sqlMember.getId(), System.currentTimeMillis() / 1000L)); + } + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.traveler)) { + Database.PATREONTable.updateTier(sqlMember.getId(), Patreon.TRAVELER); + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.advanturer)) { + Database.PATREONTable.updateTier(sqlMember.getId(), Patreon.ADVANTURER); + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.pioneer)) { + Database.PATREONTable.updateTier(sqlMember.getId(), Patreon.PIONEER); + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.wizzard)) { + Database.PATREONTable.updateTier(sqlMember.getId(), Patreon.WIZARD); + } + } + } + + @SubscribeEvent + public void onRoleRemove(@NotNull GuildMemberRoleRemoveEvent event) { + if (event.getGuild() == TechDiscordBot.getMainGuild()) { + log(event.getMember(), false, event.getRoles()); + } + + for (Role role : event.getRoles()) { + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.patreon)) { + Common.log("Patreon role removed from " + event.getMember().getUser().getAsTag()); + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.traveler)) { + Common.log("Patreon Traveler role removed from " + event.getMember().getUser().getAsTag()); + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.advanturer)) { + Common.log("Patreon advanturer role removed from " + event.getMember().getUser().getAsTag()); + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.pioneer)) { + Common.log("Patreon pioneer role removed from " + event.getMember().getUser().getAsTag()); + } + if (role == SimpleRoles.getRoleById(event.getGuild(), Settings.Roles.Patreon.wizzard)) { + Common.log("Patreon wizzard role removed from " + event.getMember().getUser().getAsTag()); + } + } + + } + + private void log(@NotNull Member member, boolean added, @NotNull List<Role> roles) { + + StringBuilder roleMentionBuilder = new StringBuilder(); + StringBuilder roleBuilder = new StringBuilder(); + + for (Role role : roles) { + roleMentionBuilder.append(role.getAsMention()).append(" "); + roleBuilder.append(role.getName()).append(" "); + } + + SimpleEmbedBuilder embedBuilder = new SimpleEmbedBuilder(added ? "Roles added!" : "Roles removed!") + .field("Member:", member.getAsMention(), true) + .field("Roles:", roleMentionBuilder.toString(), true) + .field("ID:", member.getId(), true) + .thumbnail(member.getUser().getAvatarUrl()); + + if (added) { + Logs.RoleLogs.log(embedBuilder.success()); + Common.log("Roles added to " + ConsoleColor.CYAN + member.getUser().getAsTag() + ConsoleColor.RESET + "; "+ roleBuilder); + } else { + Logs.RoleLogs.log(embedBuilder.error()); + Common.log( "Roles removed from " + ConsoleColor.CYAN + member.getUser().getAsTag() + ConsoleColor.RESET + "; "+ roleBuilder); + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/StaffEmbedModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/StaffEmbedModule.java new file mode 100644 index 00000000..7edd834d --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/StaffEmbedModule.java @@ -0,0 +1,20 @@ +package me.techscode.techdiscordbot.modules; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +/** + * TODO: Fix all the comment and finish this file! + */ +public class StaffEmbedModule extends ListenerAdapter { + + /** + * Listens for mentions of the bot. + * @param event message received event + */ + @Override + public void onMessageReceived(MessageReceivedEvent event) { + + // TODO: Finish the code + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/TicketModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/TicketModule.java new file mode 100644 index 00000000..cea524d1 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/TicketModule.java @@ -0,0 +1,373 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.debug.Debugger; +import com.greazi.discordbotfoundation.settings.SimpleSettings; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.actions.buttons.TicketButtons; +import me.techscode.techdiscordbot.actions.menus.TicketMenus; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.TranscriptDatabase; +import me.techscode.techdiscordbot.database.entities.SqlTicket; +import me.techscode.techdiscordbot.database.entities.SqlTranscript; +import me.techscode.techdiscordbot.model.Logs; +import me.techscode.techdiscordbot.model.enums.Plugin; +import me.techscode.techdiscordbot.model.enums.Ticket; +import me.techscode.techdiscordbot.settings.Settings; +import me.techscode.techdiscordbot.transcripts.TicketTranscript; +import me.techscode.techdiscordbot.transcripts.TicketTranscriptOptions; +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.Member; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.PrivateChannel; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; +import net.dv8tion.jda.api.requests.restaction.CacheRestAction; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.util.*; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; + +public class TicketModule { + + private static final String TICKET_CHANNEL_ID = Settings.Modules.Ticket.channel; + + public static void embed() { + + if (!Settings.Modules.Ticket.enabled) return; + + // The Verification text channel + final TextChannel channel = Objects.requireNonNull(TechDiscordBot.getJDA().getGuildById(SimpleSettings.Bot.MainGuild())).getTextChannelById(TICKET_CHANNEL_ID); + + // Create the verification embed + final SimpleEmbedBuilder embed = new SimpleEmbedBuilder("📨 Tickets") + .text( + "Click the button below to create a ticket", + "", + "**NOTE;**", + "**1.** You can have a maximum of 3 tickets open at a time.", + "**2.** If you see no one online it doesn't mean you are alone in the ticket. Discord doesn't show offline members. If you are in a ticket and no one is responding, please wait patiently.", + "", + "**Data Collection;**", + "We are currently gathering ticket data and messages contained within tickets to assist in the training of an Auto Response system. When you make a ticket, you understand and agree that your data will be collected." + ) + .color(new Color(81, 153, 226)); + + // Debug message to see what the ticket channel is + assert channel != null; + Debugger.debug("Tickets", "channel name == " + channel.getName() + " channel id == " + channel.getId()); + + // Send the embed with the buttons to the verification channel + channel.sendMessageEmbeds(embed.build()) + .setActionRow( + new TicketButtons.TicketButton().build() + ).queue(); + } + + @NotNull + public static CompletableFuture<TextChannel> ticketCreate(final Member creator, final Guild guild, Member owner) { + + if (Database.TICKETS.getFromMembedId(owner.getId()).size() >= 3) { + return CompletableFuture.completedFuture(null); + } + + + // Permissions list for the ticket channel + final List<Permission> permissions = new ArrayList<>( + Arrays.asList( + Permission.VIEW_CHANNEL, + Permission.MESSAGE_HISTORY + ) + ); + + // Permissions list for the ticket channel + final List<Permission> staffPermissions = new ArrayList<>( + Arrays.asList( + Permission.VIEW_CHANNEL, + Permission.MESSAGE_HISTORY, + Permission.MESSAGE_SEND, + Permission.MESSAGE_ATTACH_FILES, + Permission.MESSAGE_EMBED_LINKS, + Permission.MESSAGE_ADD_REACTION, + Permission.MANAGE_EMOJIS_AND_STICKERS + ) + ); + + // Get the members name if the members name can't be gathered it will use the user's ID + final String memberName; + if (Objects.equals(owner.getNickname(), "") || owner.getNickname() == null) { + if (owner.getEffectiveName().equals("")) { + memberName = owner.getUser().getId(); + } else { + owner.getEffectiveName(); + memberName = owner.getEffectiveName(); + } + } else { + memberName = owner.getNickname(); + } + + // Get some settings from the settings file + final Category category = guild.getCategoryById(Settings.Modules.Ticket.Category.support); + final long staffRole = Settings.Roles.staff; + + CompletableFuture<TextChannel> future = new CompletableFuture<>(); + + // Create the application channel for the member + guild.createTextChannel("ticket-" + memberName, category) + .addPermissionOverride(guild.getPublicRole(), null, permissions) + // Add staff permissions + .addRolePermissionOverride(staffRole, staffPermissions, null) + // Add member permissions + .addMemberPermissionOverride(owner.getIdLong(), permissions, Collections.singleton(Permission.MESSAGE_SEND)) + .queue(channel -> { + + channel.sendMessageEmbeds(new SimpleEmbedBuilder("📨 Ticket") + .text( + "Please select what kind of ticket you want to create.", + "", + "**Available categories:**", + Ticket.Category.PLUGIN.getEmojiRaw() + " " + Ticket.Category.PLUGIN.getName() + " - " + Ticket.Category.PLUGIN.getDescription(), + Ticket.Category.PAYMENTS.getEmojiRaw() + " " + Ticket.Category.PAYMENTS.getName() + " - " + Ticket.Category.PAYMENTS.getDescription(), + Ticket.Category.DEVELOPER.getEmojiRaw() + " " + Ticket.Category.DEVELOPER.getName() + " - " + Ticket.Category.DEVELOPER.getDescription(), + Ticket.Category.GIVEAWAY.getEmojiRaw() + " " + Ticket.Category.GIVEAWAY.getName() + " - " + Ticket.Category.GIVEAWAY.getDescription(), + Ticket.Category.PATREON.getEmojiRaw() + " " + Ticket.Category.PATREON.getName() + " - " + Ticket.Category.PATREON.getDescription(), + Ticket.Category.OTHER.getEmojiRaw() + " " + Ticket.Category.OTHER.getName() + " - " + Ticket.Category.OTHER.getDescription(), + "", + "*Please keep in mind that in order to access support for any premium resource, you must first verify your purchase.*" + ) + .build() + ).addActionRow(new TicketMenus.TicketMenu(creator).build()).queue(); + + new SqlTicket(owner.getIdLong(), channel.getIdLong(), channel.getTimeCreated().toEpochSecond(), null, null, null).save(); + + future.complete(channel); + }); + + if (owner != creator) { + Logs.TicketLogs.log(new SimpleEmbedBuilder("Ticket Created") + .text( + "Ticket created by " + creator.getAsMention() + " for " + owner.getAsMention(), + "", + "**Ticket:** " + future.join().getName() + " (" + future.join().getId() + ")" + ) + ); + } else { + Logs.TicketLogs.log(new SimpleEmbedBuilder("Ticket Created") + .text( + "Ticket created by " + creator.getAsMention(), + "", + "**Ticket:** " + future.join().getName() + " (" + future.join().getId() + ")" + ) + ); + } + + return future; + } + + public static void finishTicketCreation(@NotNull final TextChannel channel, final Member member) { + final SqlTicket sqlTicket = Database.TICKETS.get(channel.getIdLong()).get(0); + + final Ticket.Category category = Ticket.Category.valueOf(sqlTicket.getCategory()); + final Ticket.Priority priority = Ticket.Priority.valueOf(sqlTicket.getPriority()); + final Member sqlTicketMember = sqlTicket.getMember().getDiscordMember(); + + if (priority == Ticket.Priority.PATREON) { + channel.getManager().setName("❗" + channel.getName()).queue(); + } + + + if (sqlTicket.getType() == null) { + channel.sendMessageEmbeds(new SimpleEmbedBuilder("Ticket - " + sqlTicket.getMember().getDiscordMember().getUser().getAsTag()) + .text( + ) + .field("Category", category.getEmoji().getFormatted() + " " + category.getName(), true) + .field("Priority", priority.getEmoji().getFormatted() + " " + priority.getName(), true) + + .success().build()).queue(message -> { + message.pin().queue(); + } + ); + + if (member == sqlTicketMember) { + channel.getManager().setTopic( + "This ticket has been created by " + member.getAsMention() + "\n" + + " **- Created at:** <t:" + sqlTicket.getTime() + ":R>\n" + + " **- Category:** " + category.getEmoji().getFormatted() + " " + category.getName() + "\n" + + " **- Priority:** " + priority.getEmoji().getFormatted() + " " + priority.getName() + ).queue(); + } else { + channel.getManager().setTopic( + "This ticket has been created by " + member.getAsMention() + " for: " + sqlTicketMember.getAsMention() + "\n" + + " **- Created at:** <t:" + sqlTicket.getTime() + ":R>\n" + + " **- Category:** " + category.getEmoji().getFormatted() + " " + category.getName() + "\n" + + " **- Priority:** " + priority.getEmoji().getFormatted() + " " + priority.getName() + ).queue(); + } + } else { + + final SimpleEmbedBuilder embedBuilder = new SimpleEmbedBuilder("📨 Ticket - " + sqlTicketMember.getUser().getAsTag()) + .text( + "Thank you for contacting our support team, a member of our team will be with you shortly.", + "While you wait for a member of our team to respond, please provide as much information as possible about your issue/question.", + "", + "Information about your ticket;" + ) + .field("Category", category.getEmoji().getFormatted() + " " + category.getName(), true); + + String topic = "This ticket has been created by " + member.getAsMention() + "\n" + + " **- Created at:** <t:" + sqlTicket.getTime() + ":R>\n" + + " **- Category:** " + category.getEmoji().getFormatted() + " " + category.getName() + "\n"; + + if (sqlTicket.getCategory().equals(Ticket.Category.PLUGIN.getId())) { + final Plugin type = Plugin.valueOf(sqlTicket.getType()); + embedBuilder.field("Sub Category", type.getEmojiRaw() + " " + type.getName(), true); + topic = topic + " **- Sub Category:** " + type.getEmoji().getFormatted() + " " + type.getName() + "\n"; + } + if (sqlTicket.getCategory().equals(Ticket.Category.PAYMENTS.getId())) { + final Ticket.Payment type = Ticket.Payment.valueOf(sqlTicket.getType()); + embedBuilder.field("Sub Category", type.getEmojiRaw() + " " + type.getName(), true); + topic = topic + " **- Sub Category:** " + type.getEmojiRaw() + " " + type.getName() + "\n"; + } + if (sqlTicket.getCategory().equals(Ticket.Category.DEVELOPER.getId())) { + final Ticket.Developer type = Ticket.Developer.valueOf(sqlTicket.getType()); + embedBuilder.field("Sub Category", type.getEmojiRaw() + " " + type.getName(), true); + topic = topic + " **- Sub Category:** " + type.getEmojiRaw() + " " + type.getName() + "\n"; + } + if (sqlTicket.getCategory().equals(Ticket.Category.GIVEAWAY.getId())) { + final Ticket.Giveaway type = Ticket.Giveaway.valueOf(sqlTicket.getType()); + embedBuilder.field("Sub Category", type.getEmojiRaw() + " " + type.getName(), true); + topic = topic + " **- Sub Category:** " + type.getEmojiRaw() + " " + type.getName() + "\n"; + } + if (sqlTicket.getCategory().equals(Ticket.Category.PATREON.getId())) { + final Ticket.Patreon type = Ticket.Patreon.valueOf(sqlTicket.getType()); + embedBuilder.field("Sub Category", type.getEmojiRaw() + " " + type.getName(), true); + topic = topic + " **- Sub Category:** " + type.getEmojiRaw() + " " + type.getName() + "\n"; + } + + channel.sendMessageEmbeds(embedBuilder + .field("Priority", priority.getEmoji().getFormatted() + " " + priority.getName(), true) + .success().build()).queue(message -> { + message.pin().queue(); + } + ); + + channel.getManager().setTopic(topic + " **- Priority:** " + priority.getEmoji().getFormatted() + " " + priority.getName()).queue(); + } + + if (category == Ticket.Category.PLUGIN) { + channel.sendMessageEmbeds(new SimpleEmbedBuilder("Information") + .text( + "Please provide the following information:", + "\u200E " + ) + .field("Plugin Version", "`/about {Plugin}`", true) + .field("Server Version & Build", "`/about`", true) + .field("Plugin List", "`/plugins`", true) + .field("Error", "The error you are getting. *(If there is one)*", false) + .field("Additional Information", "Any additional information you think is important.", false) + .build() + ).queue(); + } + + // Permissions list for the ticket channel + final List<Permission> permissions = new ArrayList<>( + Arrays.asList( + Permission.VIEW_CHANNEL, + Permission.MESSAGE_HISTORY, + Permission.MESSAGE_SEND, + Permission.MESSAGE_ATTACH_FILES, + Permission.MESSAGE_EMBED_LINKS, + Permission.MESSAGE_ADD_REACTION, + Permission.MANAGE_EMOJIS_AND_STICKERS + ) + ); + channel.getManager().putMemberPermissionOverride(sqlTicket.getMember().getDiscordId(), permissions, null).queue(); + } + + public static void ticketClose(Member member, @NotNull final SqlTicket sqlTicket, final long unixTime, final String reason, int delay) { + TextChannel textChannel = sqlTicket.getChannel(); + + TicketTranscript transcript = TicketTranscript.buildTranscript(textChannel, TicketTranscriptOptions.DEFAULT); + + transcript.build(object -> { + if (sqlTicket.getMember().getDiscordMember() != null) { + Logs.TicketLogs.log( + new SimpleEmbedBuilder("Ticket Transcript (Command)") + .text("Transcript of " + textChannel.getName() + " (" + textChannel.getId() + "): " + transcript.getUrl()) + .color(Color.ORANGE) + ); + } + + textChannel.sendMessageEmbeds( + new SimpleEmbedBuilder("Ticket Transcript") + .text("Transcript of " + textChannel.getName() + " (" + textChannel.getId() + "): " + transcript.getUrl()) + .color(Color.ORANGE) + .build() + ).queue(); + + TranscriptDatabase.TRANSCRIPT.add(new SqlTranscript(object.get("id").getAsString(), object.toString())); + }); + + ticketRemove(textChannel, delay); + + if (delay >= 3600000) { + textChannel.sendMessageEmbeds(new SimpleEmbedBuilder("Ticket - " + textChannel.getName()) + .text("This ticket will be closed in " + TimeUnit.MILLISECONDS.toHours(delay) + " hours.", + "**Time closed:** <t:" + unixTime + ":R>", + "**Reason:** " + reason) + .error().build()).queue(); + } else { + textChannel.sendMessageEmbeds(new SimpleEmbedBuilder("Ticket - " + textChannel.getName()) + .text("This ticket will be closed in " + TimeUnit.MILLISECONDS.toMinutes(delay) + " minutes.", + "**Time closed:** <t:" + unixTime + ":R>", + "**Reason:** " + reason) + .error().build()).queue(); + } + + Common.dm(sqlTicket.getMember().getDiscordUser(), new SimpleEmbedBuilder("📨 Ticket closed") + .text("Your ticket has been closed by " + member.getAsMention() + ".", + "**Time closed:** <t:" + unixTime + ":R>", + "**Reason:** " + reason) + .error()); + + Logs.TicketLogs.log(new SimpleEmbedBuilder("Ticket closed") + .text("Ticket " + textChannel.getName() + " (" + textChannel.getId() + ") has been closed by " + member.getAsMention() + ".", + "**Time closed:** <t:" + unixTime + ":R>", + "**Reason:** " + reason) + .error()); + + /*TicketTranscript transcript = TicketTranscript.buildTranscript(ticketChannel, TicketTranscriptOptions.DEFAULT); + String channelId = ticketChannel.getId(); + + transcript.build(object -> { + Common.warning("test-3.1"); + new SimpleEmbedBuilder("Transcript") + .text("You can view your recently closed ticket's transcript here:\n" + transcript.getUrl()) + .color(Color.ORANGE) + .queue(member); + + Common.warning("test-3.2"); + new SqlTranscript(object.get("id").getAsString(), object.toString()).save(); + Common.warning("test-3.3"); + });*/ + + } + + private static void ticketRemove(@NotNull final TextChannel ticketChannel, int delay) { + final Thread thread = new Thread(() -> { + try { + Thread.sleep(delay); + } catch (final InterruptedException e) { + e.printStackTrace(); + } + ticketChannel.delete().queue(); + Database.TICKETS.remove(ticketChannel.getIdLong()); + }); + thread.setName("TicketClose" + ticketChannel.getId()); + thread.start(); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/VerificationModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/VerificationModule.java new file mode 100644 index 00000000..11df3785 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/VerificationModule.java @@ -0,0 +1,118 @@ +package me.techscode.techdiscordbot.modules; + +import com.greazi.discordbotfoundation.debug.Debugger; +import com.greazi.discordbotfoundation.settings.SimpleSettings; +import com.greazi.discordbotfoundation.utils.SimpleEmbedBuilder; +import me.techscode.techdiscordbot.TechDiscordBot; +import me.techscode.techdiscordbot.actions.buttons.verification.*; +import me.techscode.techdiscordbot.database.Database; +import me.techscode.techdiscordbot.database.entities.verification.SqlVerification; +import me.techscode.techdiscordbot.model.enums.Marketplace; +import me.techscode.techdiscordbot.settings.Settings; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.entities.channel.concrete.Category; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; + +import java.awt.*; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +/** + * The main verification moduel + */ +public class VerificationModule { + + // ---------------------------------------------------------------------------------------- + // Static + // ---------------------------------------------------------------------------------------- + + /** + * The verification channel ID + */ + private static final String VERIFICATION_CHANNEL_ID = Settings.Modules.Verification.channel; + + // ---------------------------------------------------------------------------------------- + // Methods + // ---------------------------------------------------------------------------------------- + + /** + * The main verification embed that has the market buttons under-need it + */ + public static void embed() { + + Debugger.debug("Verification", "Sending verification embed in channel " + VERIFICATION_CHANNEL_ID); + // The Verification text channel + final TextChannel channel = Objects.requireNonNull(TechDiscordBot.getJDA().getGuildById(SimpleSettings.Bot.MainGuild())).getTextChannelById(VERIFICATION_CHANNEL_ID); + + // Create the verification embed + final SimpleEmbedBuilder embed = new SimpleEmbedBuilder("Verification | How it works") + .text( + "Welcome to the verification channel. Press the button below to verify your purchase. If you have any questions, please ask around in <#311178000026566658>" + /*"Welcome to the verification channel. If you have purchased any product of TechsCode you can verify your purchase here. Simply click on the button of the marketplace you purchased from and follow the instructions. If you have any questions, please ask around in <#311178000026566658>", + "", + "Select your marketplace down below to start the verification process", + "", + "**Note:** *Do not use Polymart verification. This is enabled only for me <@619084935655063552> to test it out!*", + "", + "**Questions, Bug reports, Suggestions/Feedback needs to be send directly to <@619084935655063552>**"*/ + ) + .color(new Color(81, 153, 226)); + + // Debug message to see what the verification channel is + assert channel != null; + Debugger.debug("Verification", "channel name == " + channel.getName() + " channel id == " + channel.getId()); + + // Send the embed with the buttons to the verification channel + channel.sendMessageEmbeds(embed.build()) + .setActionRow( + new VerifyButton.Button().build() + /*new SpigotButton.Button().build(), + new BuiltByBitButton.Button().build(), + new SongodaButton.Button().build(), + new PolymartButton.Button().build()*/ + ).queue(); + } + + public static void pinger(Guild guild) { + // A system that checks every hour if a channel is still there. + // This is for all channels in category 1168185109543931964 + // If the channel is there after 24 hours of the creationg time of that channel + // It will ping Leadership role + // If there is no channel or the channel is jonger than 24 hours it will do nothing + + // Get the category + final Category category = guild.getCategoryById("1168185109543931964"); + + // Get all the channels in the category + List<TextChannel> channels = category.getTextChannels(); + + // Loop through all the channels + for (TextChannel channel : channels) { + // Get the creation time of the channel + long creationTime = channel.getTimeCreated().toEpochSecond(); + + // Get the current time + long currentTime = System.currentTimeMillis() / 1000L; + + // Get the difference between the creation time and the current time + long difference = currentTime - creationTime; + + // If the difference is bigger than 24 hours + if (difference > 86400) { + // Check if leadership has been pinged + if (channel.getTopic() == null || !channel.getTopic().contains("Leadership has been pinged")) { + // If not, add it to the topic + channel.getManager().setTopic(channel.getTopic() + " | Leadership has been pinged").queue(); + // Ping the leadership role + channel.sendMessage("<@&" + Settings.Roles.leadership + ">").queue(); + } else { + // If so, do nothing + return; + } + } + } + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/WrongChannelModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/WrongChannelModule.java new file mode 100644 index 00000000..51158dd8 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/WrongChannelModule.java @@ -0,0 +1,20 @@ +package me.techscode.techdiscordbot.modules; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +/** + * TODO: Fix all the comment and finish this file! + */ +public class WrongChannelModule extends ListenerAdapter { + + /** + * Listens for mentions of the bot. + * @param event message received event + */ + @Override + public void onMessageReceived(MessageReceivedEvent event) { + + // TODO: Finish the code + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/modules/serverStatusModule.java b/src/main/java/me/TechsCode/TechDiscordBot/modules/serverStatusModule.java new file mode 100644 index 00000000..3476510b --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/modules/serverStatusModule.java @@ -0,0 +1,20 @@ +package me.techscode.techdiscordbot.modules; + +import net.dv8tion.jda.api.events.message.MessageReceivedEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; + +/** + * TODO: Fix all the comment and finish this file! + */ +public class serverStatusModule extends ListenerAdapter { + + /** + * Listens for mentions of the bot. + * @param event message received event + */ + @Override + public void onMessageReceived(MessageReceivedEvent event) { + + // TODO: Finish the code + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQL.java b/src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQL.java deleted file mode 100644 index 7f072f1c..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQL.java +++ /dev/null @@ -1,83 +0,0 @@ -package me.TechsCode.TechDiscordBot.mysql; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; - -public class MySQL { - - private final List<String> errorMessages; - private final MySQLSettings mySQLSettings; - - private MySQL(MySQLSettings mySQLSettings) { - this.errorMessages = new ArrayList<>(); - this.mySQLSettings = mySQLSettings; - } - - public static MySQL of(MySQLSettings mySQLSettings) { - return new MySQL(mySQLSettings); - } - - public String update(String query) { - try { - Connection connection = getConnection(); - PreparedStatement p = connection.prepareStatement(query); - p.execute(); - connection.close(); - p.close(); - - return "Success"; - } catch(SQLException ex) { - ex.printStackTrace(); - errorMessages.add(ex.getMessage()); - return ex.getMessage(); - } - } - - public String update(String query, Object... objs) { - try { - Connection connection = getConnection(); - PreparedStatement p = connection.prepareStatement(query); - - int i = 1; - for(Object obj : objs) { - if(obj instanceof String) { - p.setString(i, (String) obj); - } else if(obj instanceof Boolean) { - p.setBoolean(i, (Boolean)obj); - } else { - p.setObject(i, obj); - } - - i++; - } - - p.execute(); - connection.close(); - p.close(); - - return "Success"; - } catch(SQLException ex) { - ex.printStackTrace(); - errorMessages.add(ex.getMessage()); - return ex.getMessage(); - } - } - - public Connection getConnection() throws SQLException { - String connectString = "jdbc:mysql://" + mySQLSettings.getHost() + ":" + mySQLSettings.getPort() + "/" + mySQLSettings.getDatabase() + "?useSSL=false&useUnicode=true&serverTimezone=UTC"; - return DriverManager.getConnection(connectString, mySQLSettings.getUsername(), mySQLSettings.getPassword()); - } - - public String getLatestErrorMessage() { - if(errorMessages.size() == 0) return ""; - return errorMessages.get(errorMessages.size() - 1); - } - - public List<String> getErrorMessages() { - return errorMessages; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQLSettings.java b/src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQLSettings.java deleted file mode 100644 index 47a3c685..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/mysql/MySQLSettings.java +++ /dev/null @@ -1,38 +0,0 @@ -package me.TechsCode.TechDiscordBot.mysql; - -public class MySQLSettings { - - private final String host, database, username, password, port; - - private MySQLSettings(String host, String port, String database, String username, String password) { - this.host = host; - this.port = port; - this.database = database; - this.username = username; - this.password = password; - } - - public static MySQLSettings of(String host, String port, String database, String username, String password) { - return new MySQLSettings(host, port, database, username, password); - } - - public String getHost() { - return host; - } - - public String getPort() { - return port; - } - - public String getDatabase() { - return database; - } - - public String getUsername() { - return username; - } - - public String getPassword() { - return password; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Mute.java b/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Mute.java deleted file mode 100644 index 1a1fd17c..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Mute.java +++ /dev/null @@ -1,60 +0,0 @@ -package me.TechsCode.TechDiscordBot.mysql.storage; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import net.dv8tion.jda.api.entities.Member; - -public class Mute { - - public final int id; - public final String memberId, reason; - public final long end; - public final boolean expired; - - public Mute(int id, String memberId, String reason, long end, boolean expired) { - this.id = id; - this.memberId = memberId; - this.reason = reason; - this.end = end; - this.expired = expired; - } - - public Mute(String memberId, String reason, long end, boolean expired) { - this.id = -1; - this.memberId = memberId; - this.reason = reason; - this.end = end; - this.expired = expired; - } - - public Member getMember() { - return TechDiscordBot.getGuild().getMemberById(memberId); - } - - public String getMemberId() { - return memberId; - } - - public int getId() { - return id; - } - - public long getEnd() { - return end; - } - - public boolean doesExpire() { - return end != -1L; - } - - public String getReason() { - return reason; - } - - public boolean hasReason() { - return reason != null; - } - - public boolean isExpired() { - return expired; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Preorder.java b/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Preorder.java deleted file mode 100644 index cb0d89ef..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Preorder.java +++ /dev/null @@ -1,35 +0,0 @@ -package me.TechsCode.TechDiscordBot.mysql.storage; - -public class Preorder { - - private final String plugin, email, discordName, transactionId; - private final long discordId; - - public Preorder(String plugin, String email, long discordId, String discordName, String transactionId) { - this.plugin = plugin; - this.email = email; - this.discordId = discordId; - this.discordName = discordName; - this.transactionId = transactionId; - } - - public String getPlugin() { - return plugin; - } - - public String getEmail() { - return email; - } - - public String getDiscordName() { - return discordName; - } - - public long getDiscordId() { - return discordId; - } - - public String getTransactionId() { - return transactionId; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Storage.java b/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Storage.java deleted file mode 100644 index 7bd8bcbb..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Storage.java +++ /dev/null @@ -1,379 +0,0 @@ -package me.TechsCode.TechDiscordBot.mysql.storage; - -import com.google.gson.JsonObject; -import me.TechsCode.TechDiscordBot.mysql.MySQL; -import me.TechsCode.TechDiscordBot.mysql.MySQLSettings; -import me.TechsCode.TechDiscordBot.reminders.Reminder; -import me.TechsCode.TechDiscordBot.reminders.ReminderType; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.User; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashSet; -import java.util.Set; - -public class Storage { - - private final MySQL mysql; - private boolean connected; - - private final String VERIFICATIONS_TABLE = "VerificationsOld"; - private final String REMINDERS_TABLE = "Reminders"; - private final String MUTES_TABLE = "Mutes"; - private final String SUB_VERIFICATIONS_TABLE = "SubVerifications"; - private final String TRANSCRIPTS_TABLE = "Transcripts"; - private final String PLUGIN_UPDATES_TABLE = "PluginUpdates"; - private final String WARNINGS_TABLE = "Warnings"; - - private Storage(MySQLSettings mySQLSettings) { - this.connected = false; - this.mysql = MySQL.of(mySQLSettings); - - createDefault(); - } - - public static Storage of(MySQLSettings mySQLSettings) { - return new Storage(mySQLSettings); - } - - public String getLatestErrorMessage() { - return mysql.getLatestErrorMessage(); - } - - public boolean isConnected() { - return connected; - } - - public void createDefault() { - mysql.update("CREATE TABLE IF NOT EXISTS " + VERIFICATIONS_TABLE + " (userid varchar(10), discordid varchar(32));"); - mysql.update("CREATE TABLE IF NOT EXISTS " + MUTES_TABLE + " (memberId varchar(32), reason longtext, end varchar(32), expired tinyint(1));"); - mysql.update("CREATE TABLE IF NOT EXISTS " + REMINDERS_TABLE + " (user_id varchar(32), channel_id varchar(32), time varchar(32), type tinyint(1), reminder longtext);"); - mysql.update("CREATE TABLE IF NOT EXISTS " + SUB_VERIFICATIONS_TABLE + " (discordId_verified varchar(32), discordId_subVerified varchar(32));"); - mysql.update("CREATE TABLE IF NOT EXISTS " + TRANSCRIPTS_TABLE + " (id varchar(36), value longtext) DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;"); - mysql.update("CREATE TABLE IF NOT EXISTS " + PLUGIN_UPDATES_TABLE + " (resourceId varchar(32), updateId varchar(32), PRIMARY KEY (resourceId) ) DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;"); - mysql.update("CREATE TABLE IF NOT EXISTS " + WARNINGS_TABLE + " (id varchar(32), memberId varchar(32), reporterId varchar(32), reason longtext, time varchar(32), PRIMARY KEY (id) ) DEFAULT CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;"); - - this.connected = true; - } - - //Verification - public void createVerification(String userId, String discordId) { - mysql.update("INSERT INTO " + VERIFICATIONS_TABLE + " (userid, discordid) VALUES ('" + userId + "', '" + discordId + "');"); - } - - public void removeVerification(Verification verification) { - mysql.update("DELETE FROM " + VERIFICATIONS_TABLE + " WHERE `userid`=" + verification.getUserId()); - } - - //Sub Verification - public void addSubVerification(String discordId_verified, String discordId_subVerified) { - mysql.update("INSERT INTO " + SUB_VERIFICATIONS_TABLE + " (discordId_verified, discordId_subVerified) VALUES ('" + discordId_verified + "', '" + discordId_subVerified + "');"); - } - - public void removeSubVerification(String discordId_verified) { - mysql.update("DELETE FROM " + SUB_VERIFICATIONS_TABLE + " WHERE `discordId_verified`=" + discordId_verified); - } - - public boolean hasSubVerification(String discordId_verified) { - boolean hasSubVerification = false; - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + SUB_VERIFICATIONS_TABLE + " WHERE `discordId_verified`=" + discordId_verified); - - ResultSet rs = preparedStatement.executeQuery(); - hasSubVerification = rs.next(); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return hasSubVerification; - } - - public boolean isSubVerifiedUser(String discordId_subVerified) { - boolean isSubVerifiedUser = false; - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + SUB_VERIFICATIONS_TABLE + " WHERE `discordId_subVerified`=" + discordId_subVerified); - - ResultSet rs = preparedStatement.executeQuery(); - isSubVerifiedUser = rs.next(); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return isSubVerifiedUser; - } - - public String getVerifiedIdFromSubVerifiedId(String discordId_subVerified) { - String pluginHolder = null; - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + SUB_VERIFICATIONS_TABLE + " WHERE `discordId_subVerified`=" + discordId_subVerified); - - ResultSet rs = preparedStatement.executeQuery(); - while (rs.next()) { - pluginHolder = rs.getString("discordId_verified"); - } - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return pluginHolder; - } - - public String getSubVerifiedIdFromVerifiedId(String discordId_verified) { - String pluginHolder = null; - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + SUB_VERIFICATIONS_TABLE + " WHERE `discordId_verified`=" + discordId_verified); - - ResultSet rs = preparedStatement.executeQuery(); - while (rs.next()) { - pluginHolder = rs.getString("discordId_subVerified"); - } - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return pluginHolder; - } - - public Verification retrieveVerificationWithDiscord(User user) { return retrieveVerificationWithDiscord(user.getId()); } - - public Verification retrieveVerificationWithDiscord(Member member) { return retrieveVerificationWithDiscord(member.getUser().getId()); } - - public Verification retrieveVerificationWithDiscord(String discordId) { return retrieveVerifications().stream().filter(verification -> verification.getDiscordId().equals(discordId)).findFirst().orElse(null); } - - public Verification retrieveVerificationWithSpigot(String userId) { return retrieveVerifications().stream().filter(verification -> verification.getUserId().equals(userId)).findFirst().orElse(null); } - - public Set<Verification> retrieveVerifications() { - Set<Verification> ret = new HashSet<>(); - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + VERIFICATIONS_TABLE + ";"); - - ResultSet rs = preparedStatement.executeQuery(); - while (rs.next()) - ret.add(new Verification(this, rs.getString("userid"), rs.getString("discordid"))); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return ret; - } - - //Mutes - public Set<Mute> getMutes(Member member) { - Set<Mute> ret = new HashSet<>(); - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + MUTES_TABLE + (member == null ? ";" : " WHERE memberId='" + member.getId() + "';")); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) - ret.add(new Mute(rs.getString("memberId"), rs.getString("reason"), Long.parseLong(rs.getString("time")), rs.getBoolean("expired"))); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return ret; - } - - public Mute muteExpired(Mute mute, boolean expired) { - if(mute.getId() == -1) return mute; - - mysql.update("UPDATE " + MUTES_TABLE + " SET expired=? WHERE ", expired); - - return new Mute(mute.getId(), mute.getMemberId(), mute.getReason(), mute.getEnd(), expired); - } - - public Mute uploadMute(Mute mute) { - int id = getMutes(null).size() + 1; - - mysql.update("INSERT INTO " + MUTES_TABLE + " (memberId, reason, end, expired) VALUES (?, ?, ?, ?);", mute.getMemberId(), mute.getReason(), mute.getEnd(), mute.isExpired()); - - return new Mute(id, mute.getMemberId(), mute.getReason(), mute.getEnd(), mute.isExpired()); - } - - //Preorders - public Set<Preorder> getPreorders(String plugin, boolean all) { - Set<Preorder> ret = new HashSet<>(); - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + plugin.replace(" ", "") + "Preorders;"); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) { - String transactionId = rs.getString("transactionId"); - - if(!transactionId.equals("NONE") || all) { - ret.add(new Preorder(plugin, rs.getString("email"), rs.getLong("discordId"), rs.getString("discordName"), transactionId)); - } - } - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return ret; - } - - //Reminders - public Set<Reminder> retrieveReminders() { - Set<Reminder> ret = new HashSet<>(); - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + REMINDERS_TABLE + ";"); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) - ret.add(new Reminder(rs.getString("user_id"), rs.getString("channel_id"), Long.parseLong(rs.getString("time")), null, (rs.getInt("type") == 0 ? ReminderType.CHANNEL : ReminderType.DMs), rs.getString("reminder"))); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return ret; - } - - public void saveReminder(Reminder reminder) { - mysql.update("INSERT INTO " + REMINDERS_TABLE + " (user_id, channel_id, time, type, reminder, message_id) VALUES ('" + reminder.getUserId() + "', " + (reminder.getChannelId() == null ? "NULL" : "'" + reminder.getChannelId() + "'") + ", '" + reminder.getTime() + "', " + reminder.getType().getI() + ", '" + reminder.getReminder().replace("'", "''") + "', 'XXXX');"); - } - - public void saveTranscript(JsonObject transcript) { - mysql.update("INSERT INTO " + TRANSCRIPTS_TABLE + " (id, value) VALUES (?, ?);", transcript.get("id").getAsString(), transcript.toString()); - } - - public void deleteReminder(Reminder reminder) { - mysql.update("DELETE FROM " + REMINDERS_TABLE + " WHERE user_id='" + reminder.getUserId() + "' AND channel_id='" + (reminder.getChannelId() == null ? "NULL" : "'" + reminder.getChannelId() + "'") + "' AND time='" + reminder.getTime() + "' AND type=" + reminder.getType().getI() + " AND reminder='" + reminder.getReminder().replace("'", "''") + "';"); - } - - public String getLastPluginUpdate(String resourceId){ - String update = "unknown"; - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + PLUGIN_UPDATES_TABLE + " WHERE `resourceId`='"+resourceId+"';"); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) - update = rs.getString("updateId"); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return update; - } - - public void updateLastPluginUpdate(String resourceId, String newUpdateId){ - mysql.update("UPDATE " + PLUGIN_UPDATES_TABLE + " SET `updateId`=? WHERE `resourceId`=?;", newUpdateId, resourceId); - } - - public void insertLastPluginUpdate(String resourceId, String newUpdateId){ - mysql.update("INSERT INTO " + PLUGIN_UPDATES_TABLE + " (resourceId, updateId) VALUES (?, ?)", resourceId, newUpdateId); - } - - public boolean lastPluginExists(String resourceId){ - boolean exists = false; - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + PLUGIN_UPDATES_TABLE + " WHERE `resourceId`='"+resourceId+"';"); - ResultSet rs = preparedStatement.executeQuery(); - - exists = rs.next(); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return exists; - } - - public void addWarning(Warning warning) { - mysql.update("INSERT INTO " + WARNINGS_TABLE + " (id, memberId, reporterId, reason, time) VALUES (?, ?, ?, ?, ?);", warning.getId(), warning.getMemberId(), warning.getReporterId(), warning.getReason(), warning.getTime()); - } - - public void deleteWarning(int warningId) { - mysql.update("DELETE FROM " + WARNINGS_TABLE + " WHERE `id`=?;", warningId); - } - - public Set<Warning> retrieveWarningsByUserID(String userId) { - Set<Warning> ret = new HashSet<>(); - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + WARNINGS_TABLE + " WHERE `memberId`='"+userId+"';"); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) - ret.add(new Warning(rs.getInt("id"), rs.getString("memberId"), rs.getString("reporterId"), rs.getString("reason"), rs.getLong("time"))); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return ret; - } - - public Warning retrieveWarningById(String warningId){ - Warning warning = null; - - try { - Connection connection = mysql.getConnection(); - PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM " + WARNINGS_TABLE + " WHERE `id`='"+warningId+"';"); - ResultSet rs = preparedStatement.executeQuery(); - - while (rs.next()) - warning = new Warning(rs.getInt("id"), rs.getString("memberId"), rs.getString("reporterId"), rs.getString("reason"), rs.getLong("time")); - - rs.close(); - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - - return warning; - } - -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Verification.java b/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Verification.java deleted file mode 100644 index 158a62ea..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Verification.java +++ /dev/null @@ -1,25 +0,0 @@ -package me.TechsCode.TechDiscordBot.mysql.storage; - -public class Verification { - - private final Storage storage; - private final String userId, discordId; - - public Verification(Storage storage, String userId, String discordId) { - this.storage = storage; - this.userId = userId; - this.discordId = discordId; - } - - public String getUserId() { - return userId; - } - - public String getDiscordId() { - return discordId; - } - - public void delete() { - storage.removeVerification(this); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Warning.java b/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Warning.java deleted file mode 100644 index 4c4eeb8c..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/mysql/storage/Warning.java +++ /dev/null @@ -1,76 +0,0 @@ -package me.TechsCode.TechDiscordBot.mysql.storage; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import net.dv8tion.jda.api.entities.Member; - -import java.util.Random; - -public class Warning { - - public final int id; - public final String memberId, reporterId, reason; - public final long time; - - public Warning(String memberId, String reporterId, String reason, long time) { - Random rand = new Random(); - this.id = rand.nextInt(25); - - this.memberId = memberId; - this.reporterId = reporterId; - this.reason = reason; - this.time = time; - } - - public Warning(int id, String memberId, String reporterId, String reason, long time) { - this.id = id; - this.memberId = memberId; - this.reporterId = reporterId; - this.reason = reason; - this.time = time; - } - - public int getId() { - return id; - } - - public String getMemberId() { - return memberId; - } - - public Member getMember() { - return TechDiscordBot.getGuild().getMemberById(memberId); - } - - public String getReporterId() { - return reporterId; - } - - public Member getReporter() { - return TechDiscordBot.getGuild().getMemberById(reporterId); - } - - public String getReason() { - return reason; - } - - public boolean hasReason() { - return reason != null; - } - - public long getTime() { - return time; - } - - public String getTimeFormatted() { - return "<t:"+time / 1000+":R>"; - } - - public void save(){ - TechDiscordBot.getStorage().addWarning(this); - } - - public void delete(){ - TechDiscordBot.getStorage().deleteWarning(id); - } - -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/objects/ChannelQuery.java b/src/main/java/me/TechsCode/TechDiscordBot/objects/ChannelQuery.java deleted file mode 100644 index 6b920dc1..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/objects/ChannelQuery.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.TechsCode.TechDiscordBot.objects; - -import net.dv8tion.jda.api.entities.Category; -import net.dv8tion.jda.api.entities.TextChannel; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Collectors; - -public class ChannelQuery extends Query<TextChannel> { - - public ChannelQuery(List<TextChannel> objects) { - super(objects); - } - - public ChannelQuery inCategory(String category) { - List<TextChannel> channels = all().stream().filter(textChannel -> Objects.requireNonNull(textChannel.getParent()).getName().equalsIgnoreCase(category)).collect(Collectors.toList()); - return new ChannelQuery(channels); - } - - public ChannelQuery inCategory(Category category) { - return inCategory(category.getName()); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/objects/Cooldown.java b/src/main/java/me/TechsCode/TechDiscordBot/objects/Cooldown.java deleted file mode 100644 index ae6c48a7..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/objects/Cooldown.java +++ /dev/null @@ -1,22 +0,0 @@ -package me.TechsCode.TechDiscordBot.objects; - -import java.time.OffsetDateTime; -import java.time.temporal.ChronoUnit; - -public class Cooldown { - - private final OffsetDateTime offsetDateTime; - - public Cooldown(final OffsetDateTime time) { - this.offsetDateTime = time; - } - - public int getRemainingCooldown() { - int time = (int) Math.ceil(OffsetDateTime.now().until(offsetDateTime, ChronoUnit.MILLIS) / 1000D); - return Math.max(time, 0); - } - - public boolean isCooldownRemaining() { - return getRemainingCooldown() != 0; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/objects/DefinedQuery.java b/src/main/java/me/TechsCode/TechDiscordBot/objects/DefinedQuery.java deleted file mode 100644 index 7fe83c7d..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/objects/DefinedQuery.java +++ /dev/null @@ -1,17 +0,0 @@ -package me.TechsCode.TechDiscordBot.objects; - -public abstract class DefinedQuery<T> { - - private static final boolean ENABLE_CACHING = false; - - private Query<T> cache; - - public Query<T> query() { - if(!ENABLE_CACHING) return newQuery(); - if(cache == null) cache = newQuery(); - return cache; - } - - protected abstract Query<T> newQuery(); - -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/objects/Query.java b/src/main/java/me/TechsCode/TechDiscordBot/objects/Query.java deleted file mode 100644 index 17597bf4..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/objects/Query.java +++ /dev/null @@ -1,66 +0,0 @@ -package me.TechsCode.TechDiscordBot.objects; - -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import java.util.function.Consumer; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class Query<T> { - - protected List<T> objects; - - public Query(List<T> objects) { - this.objects = objects; - } - - public Query(Query<T> ... queries) { - this.objects = Arrays.stream(queries).flatMap(q -> q.objects.stream()).collect(Collectors.toList()); - } - - public List<T> all() { - return objects; - } - - public boolean hasAny() { - return objects.size() != 0; - } - - public boolean hasMultiple() { - return objects.size() > 1; - } - - public int amount() { - return objects.size(); - } - - public T first() { - return hasAny() ? objects.get(0) : null; - } - - public T last() { - return hasAny() ? objects.get(objects.size() - 1) : null; - } - - public T random() { - return hasAny() ? objects.get(new Random().nextInt(objects.size())): null; - } - - public T get(int i) { - return hasAny() ? objects.get(i) : null; - } - - public Query<T> filter(Predicate<? super T> predicate) { - return new Query<T>(objects.stream().filter(predicate).collect(Collectors.toList())); - } - - public Stream<T> stream() { - return all().stream(); - } - - public void forEach(Consumer<T> action) { - all().forEach(action); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/objects/Requirement.java b/src/main/java/me/TechsCode/TechDiscordBot/objects/Requirement.java deleted file mode 100644 index 879d3978..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/objects/Requirement.java +++ /dev/null @@ -1,27 +0,0 @@ -package me.TechsCode.TechDiscordBot.objects; - -import java.util.Objects; - -public class Requirement { - - private final DefinedQuery<?> query; - private final int matchesRequired; - private final String unmatchMessage; - - public Requirement(DefinedQuery<?> query, int matchesRequired, String unmatchMessage) { - Objects.requireNonNull(query, "Defined Query cannot be null!"); - Objects.requireNonNull(unmatchMessage, "Message cannot be null!"); - - this.query = query; - this.matchesRequired = matchesRequired; - this.unmatchMessage = unmatchMessage; - } - - public boolean check() { - return query.query().amount() >= matchesRequired; - } - - public String getUnmatchMessage() { - return unmatchMessage; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/objects/TicketPriority.java b/src/main/java/me/TechsCode/TechDiscordBot/objects/TicketPriority.java deleted file mode 100644 index 28dbbf61..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/objects/TicketPriority.java +++ /dev/null @@ -1,18 +0,0 @@ -package me.TechsCode.TechDiscordBot.objects; - -public enum TicketPriority { - - LOW(0), - MEDIUM(1), - HIGH(2); - - private final int i; - - TicketPriority(int i) { - this.i = i; - } - - public int getValue() { - return i; - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/reminders/Reminder.java b/src/main/java/me/TechsCode/TechDiscordBot/reminders/Reminder.java deleted file mode 100644 index c053010f..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/reminders/Reminder.java +++ /dev/null @@ -1,79 +0,0 @@ -package me.TechsCode.TechDiscordBot.reminders; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.entities.User; - -public class Reminder { - - private final String userId, channelId, humanTime, reminder; - private final long time; - private final ReminderType type; - - public Reminder(String userId, String channelId, long time, String humanTime, ReminderType type, String reminder) { - this.userId = userId; - this.channelId = channelId; - this.time = time; - this.humanTime = humanTime; - this.type = (channelId == null ? ReminderType.DMs : type); - this.reminder = reminder; - } - - public String getUserId() { - return userId; - } - - public String getChannelId() { - return channelId; - } - - public long getTime() { - return time; - } - - public String getHumanTime() { - return humanTime; - } - - public ReminderType getType() { - return type; - } - - public String getReminder() { - return reminder; - } - - public void delete() { - TechDiscordBot.getStorage().deleteReminder(this); - } - - public void send() { - User user = TechDiscordBot.getJDA().getUserById(userId); - - if(user != null) { - ReminderType type = this.type; - TextChannel channel = TechDiscordBot.getJDA().getTextChannelById(channelId); - - if(channel == null) type = ReminderType.DMs; - - if(type == ReminderType.DMs) { - try { - user.openPrivateChannel().queue(msg -> msg.sendMessage("**Reminder**: " + reminder).queue()); - } catch(Exception ex) { - if(channel == null) - return; - - sendReminder(user, channel); - } - } else { - sendReminder(user, channel); - } - } - - delete(); - } - - private void sendReminder(User user, TextChannel channel) { - channel.sendMessage("**Reminder for " + user.getAsMention() + "**: " + reminder).queue(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderManager.java b/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderManager.java deleted file mode 100644 index a08932a6..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderManager.java +++ /dev/null @@ -1,102 +0,0 @@ -package me.TechsCode.TechDiscordBot.reminders; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.entities.User; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -public class ReminderManager { - - private final List<Reminder> reminders = new ArrayList<>(); - - public void load() { - this.reminders.addAll(TechDiscordBot.getStorage().retrieveReminders()); - - checkForReminders(); - } - - private void checkForReminders() { - new Thread(() -> { - while (true) { - for (Reminder reminder : new ArrayList<>(reminders)) { - if (Math.abs(System.currentTimeMillis() - reminder.getTime()) < 100L) { - reminder.send(); - reminders.remove(reminder); - } - } - } - }).start(); - } - - public List<Reminder> getReminders() { - return this.reminders; - } - - public List<Reminder> getRemindersByUser(User user) { - return this.reminders.stream().filter(reminder -> reminder.getUserId().equals(user.getId())).collect(Collectors.toList()); - } - - public Reminder createReminder(User user, String time, String remind, TextChannel channel) { - ReminderArgResponse argResponse = argsToTime(time.split(" ")); - if(argResponse == null) return null; - - if(argResponse.getAmountOfArgs() == 0) { - return null; - } else { - List<String> reminder = new ArrayList<>(Arrays.asList(remind.split(" "))); - boolean isDM = false; - - if(reminder.get(reminder.size() - 1).equalsIgnoreCase("dms") || reminder.get(reminder.size() - 1).equalsIgnoreCase("dm")) { - reminder = reminder.subList(0, reminder.size() - 1); - isDM = true; - } - -// reminder = reminder.subList(argResponse.getAmountOfArgs(), reminder.size()); - if(reminder.size() == 0) return null; - - Reminder r = new Reminder(user.getId(), channel.getId(), argResponse.getTime(), argResponse.getTimeHuman(), (isDM ? ReminderType.DMs : ReminderType.CHANNEL), String.join(" ", reminder)); - this.reminders.add(r); - - TechDiscordBot.getStorage().saveReminder(r); - return r; - } - } - - public ReminderArgResponse argsToTime(String[] args) { - HumanTimeBuilder bhb = new HumanTimeBuilder(); - long time = System.currentTimeMillis(); - int argsAm = 0; - int i = 0; - - for(String arg : args) { - for(ReminderTimeType rtt : ReminderTimeType.values()) { - if(Arrays.stream(rtt.getNames()).anyMatch(n -> n.equalsIgnoreCase(arg))) { - if (i > 0) { - String tim = args[i - 1]; - try { - int timint = Math.abs(Integer.parseInt(tim)); - time = time + rtt.toMilli(timint); - bhb.addX(rtt, timint); - argsAm = argsAm + 2; - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - } - } - i++; - } - - return new ReminderArgResponse(time, argsAm, bhb.toString()); - } - - public void deleteReminder(Reminder reminder) { - reminder.delete(); - this.reminders.remove(reminder); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderTimeType.java b/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderTimeType.java deleted file mode 100644 index e89b5bd3..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/reminders/ReminderTimeType.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.TechsCode.TechDiscordBot.reminders; - -import java.util.concurrent.TimeUnit; - -public enum ReminderTimeType { - - YEAR(TimeUnit.DAYS, 365, "year", "years", "yr", "yrs"), - MONTH(TimeUnit.DAYS, 31, "months", "month"), - WEEK(TimeUnit.DAYS, 7, "week", "weeks"), - DAY(TimeUnit.DAYS, 1, "day", "days"), - HOUR(TimeUnit.HOURS, 1, "hr", "hour", "hours", "hour"), - MINUTE(TimeUnit.MINUTES, 1, "min", "mins", "minutes", "minute"), - SECOND(TimeUnit.SECONDS, 1, "sec", "secs", "seconds", "second"); - - private final String[] names; - private final int multiplier; - private final TimeUnit timeUnit; - - ReminderTimeType(TimeUnit unit, int multiplier, String... names) { - this.names = names; - this.multiplier = multiplier; - this.timeUnit = unit; - } - - public long toMilli(int am) { - return timeUnit.toMillis(am) * multiplier; - } - - public int getMultiplier() { - return multiplier; - } - - public TimeUnit getTimeUnit() { - return timeUnit; - } - - public String[] getNames() { - return names; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/settings/Settings.java b/src/main/java/me/TechsCode/TechDiscordBot/settings/Settings.java new file mode 100644 index 00000000..703912c1 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/settings/Settings.java @@ -0,0 +1,256 @@ +package me.techscode.techdiscordbot.settings; + +import com.greazi.discordbotfoundation.settings.SimpleSettings; + +import java.util.List; + +/** + * A very ugly way to create an settings file + * This is TEMPORARILY a better settings system + * will arrive later + */ +public class Settings extends SimpleSettings { + + public static class Roles { + static String mainPath = "Roles."; + + public static long staff = getLong(mainPath + "Staff"); + + public static long leadership = getLong(mainPath + "Leadership"); + public static long development = getLong(mainPath + "Development"); + public static long support = getLong(mainPath + "Support"); + public static long developer = getLong(mainPath + "Developer"); + public static long seniorSupporter = getLong(mainPath + "SeniorSupporter"); + public static long supporter = getLong(mainPath + "Supporter"); + public static long juniorSupporter = getLong(mainPath + "JuniorSupporter"); + + public static long verified = getLong(mainPath + "Verified"); + public static long spigot = getLong(mainPath + "Spigot"); + public static long builtByBit = getLong(mainPath + "BuiltByBit"); + public static long songoda = getLong(mainPath + "Songoda"); + public static long polymart = getLong(mainPath + "Polymart"); + + public static long ultraPermissions = getLong(mainPath + "UltraPermissions"); + public static long ultraCustomizer = getLong(mainPath + "UltraCustomizer"); + public static long ultraEconomy = getLong(mainPath + "UltraEconomy"); + public static long ultraPunishments = getLong(mainPath + "UltraPunishments"); + public static long ultraRegions = getLong(mainPath + "UltraRegions"); + public static long ultraScoreboards = getLong(mainPath + "UltraScoreboards"); + public static long ultraMotd = getLong(mainPath + "UltraMotd"); + public static long insaneShops = getLong(mainPath + "InsaneShops"); + public static long insaneVaults = getLong(mainPath + "InsaneVaults"); + public static long insaneAnnouncer = getLong(mainPath + "InsaneAnnouncer"); + + public static long updates = getLong(mainPath + "Updates"); + public static long announcements = getLong(mainPath + "Announcements"); + public static long patreonNews = getLong(mainPath + "PatreonNews"); + public static long pluginLab = getLong(mainPath + "PluginLab"); + public static long giveaways = getLong(mainPath + "Giveaways"); + public static long community = getLong(mainPath + "Community"); + + public static long preorder = getLong(mainPath + "Preorder"); + + public static class Patreon { + + static String path = "Roles.Patreon."; + + public static long patreon = getLong(path + "Patreon"); + public static long traveler = getLong(path + "Traveler"); + public static long advanturer = getLong(path + "Advanturer"); + public static long pioneer = getLong(path + "Pioneer"); + public static long wizzard = getLong(path + "Wizzard"); + } + } + + public static class Modules { + + static String mainPath = "Modules."; + + public static class Logs { + + static String path = mainPath + "Logs."; + + public static long chat = getLong(path + "Chat"); + + public static long server = getLong(path + "Server"); + + public static long verification = getLong(path + "Verification"); + + public static long punish = getLong(path + "Punish"); + + public static long tickets = getLong(path + "Tickets"); + + public static long roles = getLong(path + "Roles"); + + } + + public static class SelfRoles { + + static String path = mainPath + "SelfRoles."; + + public static long channel = getLong(path + "Channel"); + } + + public static class Verification { + + static String verificationPath = mainPath + "Verification."; + + public static String enabled = getString(verificationPath + "Enabled"); + + public static String channel = getString(verificationPath + "Channel"); + + public static List<String> dmUsers = getStringList(verificationPath + "DmUsers"); + + public static long manualVerification = getLong(verificationPath + "ManualVerification"); + + public static long pingChannel = getLong(verificationPath + "PingChannel"); + + public static class UpdatePurchase { + static String purchasePath = verificationPath + "UpdatePurchase."; + + public static boolean enabled = getBoolean(purchasePath + "Enabled"); + } + + public static class Api { + static String apiPath = verificationPath + "Api."; + + public static class Paypal { + static String paypalPath = apiPath + "Paypal."; + + public static String link() { + String link = getString(paypalPath + "Link"); + if (!link.endsWith("/")) { + link = link + "/"; + } + return link; + } + + public static String token() { + return getString(paypalPath + "Token"); + } + } + + public static class Spigot { + static String spigotPath = apiPath + "Spigot."; + + public static String link() { + String link = getString(spigotPath + "Link"); + if (!link.endsWith("/")) { + link = link + "/"; + } + return link; + } + + public static String token() { + return getString(spigotPath + "Token"); + } + } + + public static class McMarket { + static String mcMarketPath = apiPath + "McMarket."; + + public static String link() { + return getString(mcMarketPath + "Link"); + } + + public static String token() { + return getString(mcMarketPath + "Token"); + } + } + + public static class Songoda { + static String songodaPath = apiPath + "Songoda."; + + public static String link() { + return getString(songodaPath + "Link"); + } + + public static String token() { + return getString(songodaPath + "Token"); + } + } + + public static class Polymart { + static String PolymartPath = apiPath + "Polymart."; + + public static String link() { + return getString(PolymartPath + "Link"); + } + + public static String token() { + return getString(PolymartPath + "Token"); + } + } + } + } + + public static class Ticket { + static String ticketPath = mainPath + "Ticket."; + + public static boolean enabled = getBoolean(ticketPath + "Enabled"); + + public static String channel = getString(ticketPath + "Channel"); + + public static class Category { + static String categoryPath = ticketPath + "Category."; + + public static long support = getLong(categoryPath + "Support"); + public static long development = getLong(categoryPath + "Development"); + public static long management = getLong(categoryPath + "Management"); + + public static long greazi = getLong(categoryPath + "Greazi"); + public static long timo = getLong(categoryPath + "Timo"); + public static long lucifer = getLong(categoryPath + "Lucifer"); + public static long ghost = getLong(categoryPath + "Ghost"); + public static long fabian = getLong(categoryPath + "Fabian"); + public static long peng = getLong(categoryPath + "Peng"); + public static long das = getLong(categoryPath + "Das"); + public static long opti = getLong(categoryPath + "Opti"); + + } + } + + public static class Apply { + static String applyPath = mainPath + "Application."; + + public static boolean enabled = getBoolean(applyPath + "Enabled"); + + public static String channel = getString(applyPath + "Channel"); + + public static String category = getString(applyPath + "Category"); + } + + public static class Preorder { + static String preorderPath = mainPath + "Preorder."; + + public static boolean enabled = getBoolean(preorderPath + "Enabled"); + + public static long channel = getLong(preorderPath + "AnnounceChannel"); + } + + public static class MessageReceive { + static String messageReceivePath = mainPath + "MessageReceive."; + + public static boolean image = getBoolean(messageReceivePath + "Image"); + + public static boolean pastebin = getBoolean(messageReceivePath + "Pastebin"); + + } + } + + public static class Database { + + static String mainPath = "Database."; + + public static class Transcript { + + static String preorderPath = mainPath + "Transcript."; + + public static String username = getString(preorderPath + "Username"); + + public static String password = getString(preorderPath + "Password"); + } + + + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaAPIClient.java b/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaAPIClient.java deleted file mode 100644 index 3ba101fc..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaAPIClient.java +++ /dev/null @@ -1,93 +0,0 @@ -package me.TechsCode.TechDiscordBot.songoda; - -import com.google.gson.JsonArray; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.JsonParser; -import me.TechsCode.TechDiscordBot.client.APIClient; -import me.TechsCode.TechDiscordBot.spigotmc.data.Cost; -import me.TechsCode.TechDiscordBot.spigotmc.data.User; -import me.TechsCode.TechDiscordBot.spigotmc.data.Time; -import me.TechsCode.TechDiscordBot.util.Plugin; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.concurrent.TimeUnit; - -public class SongodaAPIClient extends APIClient { - - private final SongodaPurchaseList purchases; - private long time; - - public SongodaAPIClient(String token) { - super(token); - - this.time = 0; - this.purchases = new SongodaPurchaseList(); - } - - public boolean isLoaded() { - return purchases.size() != 0; - } - - public long getRefreshTime() { - return time; - } - - public SongodaPurchaseList getSpigotPurchases() { - return purchases; - } - - @Override - public void run() { - while (true) { - try { - URL url = new URL("https://songoda.com/api/dashboard/payments?token=" + getToken() + "&per_page=2000000"); - HttpURLConnection httpcon = (HttpURLConnection) url.openConnection(); - httpcon.addRequestProperty("User-Agent", "Mozilla/5.0"); - httpcon.connect(); - - JsonArray data = JsonParser.parseReader(new InputStreamReader((InputStream) httpcon.getContent())).getAsJsonObject().getAsJsonArray("data"); - - this.time = System.currentTimeMillis(); - this.purchases.clear(); - - data.forEach(d -> { - JsonObject object = d.getAsJsonObject(); - - String product = object.get("product").getAsString(); - String username = object.get("username").getAsString(); - String avatar = object.has("avatar") ? object.get("avatar").getAsString() : "https://imgproxy.songoda.com//fit/48/48/sm/0/plain/https://cdn2.songoda.com/avatars/default/avatar_5.png"; - String currency = object.get("currency").getAsString(); - float cost = Float.parseFloat(object.get("amount").getAsString()); - - String discord = object.get("discord").isJsonNull() ? null : object.get("discord").getAsString(); - String discordId = null; - JsonObject discordData = object.has("discord_data") && !object.get("discord_data").isJsonNull() ? object.get("discord_data").getAsJsonObject() : new JsonObject(); - if(discordData.has("id")) - discordId = discordData.get("id").getAsString(); - - long createdAt = object.get("created_at").getAsLong() * 1000; - int userId = object.get("user_id").getAsInt(); - - SongodaPurchase sp = new SongodaPurchase(Plugin.byEmojiName(product.replace(" ", "")).getResourceId(), new User(String.valueOf(userId), username, avatar), new Time(new SimpleDateFormat("MMM dd, yyyy 'at' hh:mm a").format(new Date(createdAt)), createdAt), new Cost(currency, cost), discordId == null ? discord : discordId); - - this.purchases.add(sp); - }); - - httpcon.disconnect(); - } catch (IOException | JsonParseException e) { - e.printStackTrace(); - } - - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(3L)); - } catch (InterruptedException ignored) { } - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchase.java b/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchase.java deleted file mode 100644 index 8d9bf64f..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchase.java +++ /dev/null @@ -1,45 +0,0 @@ -package me.TechsCode.TechDiscordBot.songoda; - -import com.google.gson.JsonObject; -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.spigotmc.data.Cost; -import me.TechsCode.TechDiscordBot.spigotmc.data.Purchase; -import me.TechsCode.TechDiscordBot.spigotmc.data.Time; -import me.TechsCode.TechDiscordBot.spigotmc.data.User; -import net.dv8tion.jda.api.entities.Member; - -public class SongodaPurchase extends Purchase { - - private final String discord; - - public SongodaPurchase(String resourceId, User user, Time time, Cost cost, String discord) { - super(resourceId, user, time, cost); - - this.discord = discord; - } - - public SongodaPurchase(JsonObject state, String discord) { - super(state); - - this.discord = discord; - } - - public String getDiscord() { - return discord; - } - - public Member getMember() { - if (getDiscord() == null) - return null; - if(!getDiscord().contains("#")) - return TechDiscordBot.getGuild().getMemberById(getDiscord()); - - String name = this.discord.split("#")[0]; - String discrim = this.discord.split("#")[1]; - - if (name == null || discrim == null || name.isEmpty() || discrim.isEmpty()) - return null; - - return TechDiscordBot.getGuild().getMembers().stream().filter(member -> member.getUser().getName().equals(name) && member.getUser().getDiscriminator().equals(discrim)).findFirst().orElse(null); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchaseList.java b/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchaseList.java deleted file mode 100644 index 1a99c7a9..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/songoda/SongodaPurchaseList.java +++ /dev/null @@ -1,47 +0,0 @@ -package me.TechsCode.TechDiscordBot.songoda; - -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.User; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.stream.Collectors; - -public class SongodaPurchaseList extends ArrayList<SongodaPurchase> { - - public SongodaPurchaseList() { - super(new ArrayList<>()); - } - - public SongodaPurchaseList(Collection<? extends SongodaPurchase> c) { - super(c); - } - - public SongodaPurchaseList userId(String userId) { - return new SongodaPurchaseList(this).stream().filter(purchase -> purchase.getUser().getUserId().equals(userId)).collect(Collectors.toCollection(SongodaPurchaseList::new)); - } - - public SongodaPurchaseList username(String username) { - return new SongodaPurchaseList(this).stream().filter(purchase -> purchase.getUser().getUsername().equalsIgnoreCase(username)).collect(Collectors.toCollection(SongodaPurchaseList::new)); - } - - public SongodaPurchaseList resource(String resourceId) { - return new SongodaPurchaseList(this).stream().filter(purchase -> purchase.getResource().getId().equals(resourceId)).collect(Collectors.toCollection(SongodaPurchaseList::new)); - } - - public SongodaPurchaseList gifted() { - return new SongodaPurchaseList(this).stream().filter(p -> p.getCost().isPresent() && p.getCost().get().getValue() == 0F).collect(Collectors.toCollection(SongodaPurchaseList::new)); - } - - public SongodaPurchaseList discord(String discord) { - return new SongodaPurchaseList(this).stream().filter(purchase -> purchase.getDiscord() != null && purchase.getDiscord().equals(discord)).collect(Collectors.toCollection(SongodaPurchaseList::new)); - } - - public SongodaPurchaseList discord(User user) { - return new SongodaPurchaseList(this).stream().filter(purchase -> purchase.getDiscord() != null && (purchase.getDiscord().equals(user.getId()) || purchase.getDiscord().equals(user.getName() + "#" + user.getDiscriminator()))).collect(Collectors.toCollection(SongodaPurchaseList::new)); - } - - public SongodaPurchaseList discord(Member member) { - return discord(member.getUser()); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotAPIManager.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotAPIManager.java deleted file mode 100644 index 8ddd5c47..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotAPIManager.java +++ /dev/null @@ -1,444 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc; - -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.spigotmc.data.*; -import me.TechsCode.TechDiscordBot.spigotmc.data.lists.*; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.HttpURLConnection; -import java.net.URL; - -public class SpigotAPIManager { - private static String base_url; - private static String apiToken; - - public SpigotAPIManager(String url, String token) { - base_url = url; - apiToken = token; - } - - private JsonObject makeRequest(String endPoint, String attributes) { - if(!isOnline()){ - JsonObject errorObj = new JsonObject(); - errorObj.addProperty("status", "error"); - errorObj.addProperty("msg", "API is offline"); - return errorObj; - } - - try { - URL url = new URL(base_url + endPoint + "?token=" + apiToken + attributes); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("GET"); - - BufferedReader in = new BufferedReader( - new InputStreamReader(con.getInputStream())); - String inputLine; - StringBuilder content = new StringBuilder(); - while ((inputLine = in.readLine()) != null) { - content.append(inputLine); - } - in.close(); - con.disconnect(); - - if(con.getResponseCode() == 200){ - Gson gson = new Gson(); - return gson.fromJson(content.toString(), JsonObject.class); - }else{ - JsonObject errorObj = new JsonObject(); - errorObj.addProperty("status", "error"); - errorObj.addProperty("msg", "API is offline"); - return errorObj; - } - } catch (Exception e) { - JsonObject errorObj = new JsonObject(); - errorObj.addProperty("status", "error"); - errorObj.addProperty("msg", e.getMessage()); - return errorObj; - } - } - - public boolean isOnline(){ - try { - URL url = new URL(base_url + "docs"); - HttpURLConnection con = (HttpURLConnection) url.openConnection(); - con.setRequestMethod("GET"); - con.setConnectTimeout(1000); - - con.disconnect(); - - return con.getResponseCode() == 200; - } catch (Exception e) { - return false; - } - } - - public APIWebStatus getStatus() { - if(isOnline()){ - JsonObject obj = makeRequest("status", ""); - return new APIWebStatus(obj.get("spigotFetching").getAsBoolean(), obj.get("marketFetching").getAsBoolean(), obj.get("lastSpigotFetch").getAsLong(), obj.get("lastMarketFetch").getAsLong(), obj.get("lastSpigotFetchDate").getAsString(), obj.get("lastMarketFetchDate").getAsString()); - }else{ - return new APIWebStatus(false, false, 0, 0, "Unknown", "Unknown"); - } - } - - //SPIGOT - public ProfileCommentList fetchSpigotProfileComments(String userid, boolean showAll) { - JsonObject obj = makeRequest("spigot/verifyUser", "&user=" + userid + "&showAll=" + showAll); - ProfileCommentList comments = new ProfileCommentList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return comments; - } - } - if (!obj.has("data")) { - return comments; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject comment = jsonElement.getAsJsonObject(); - - comments.add(new ProfileComment( - comment.get("commentId").getAsString(), - comment.get("userId").getAsString(), - comment.get("message").getAsString())); - } - - return comments; - } - - public ResourcesList fetchSpigotResource() { - JsonObject obj = makeRequest("data/spigot/resources", ""); - ResourcesList resources = new ResourcesList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return resources; - } - } - if (!obj.has("data")) { - return resources; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject resource = jsonElement.getAsJsonObject(); - JsonObject time = resource.get("time").getAsJsonObject(); - - Cost pluginCost = null; - if (resource.has("cost")) { - JsonObject cost = resource.get("cost").getAsJsonObject(); - pluginCost = new Cost(cost.get("currency").getAsString(), cost.get("value").getAsFloat()); - } - - resources.add(new Resource( - resource.get("id").getAsString(), - resource.get("name").getAsString(), - resource.get("tagLine").getAsString(), - resource.get("category").getAsString(), - resource.get("version").getAsString(), - pluginCost, - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()) - , "spigot")); - } - - return resources; - } - - public ReviewsList fetchSpigotReviews() { - JsonObject obj = makeRequest("data/spigot/reviews", ""); - ReviewsList reviews = new ReviewsList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return reviews; - } - } - if (!obj.has("data")) { - return reviews; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject review = jsonElement.getAsJsonObject(); - JsonObject time = review.get("time").getAsJsonObject(); - - reviews.add(new Review( - review.get("id").getAsString(), - review.get("resourceId").getAsString(), - new User(review.get("user").getAsJsonObject()), - review.get("text").getAsString(), - review.get("rating").getAsInt(), - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()))); - } - - return reviews; - } - - public UpdatesList fetchSpigotUpdates() { - JsonObject obj = makeRequest("data/spigot/updates", ""); - UpdatesList updates = new UpdatesList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return updates; - } - } - if (!obj.has("data")) { - return updates; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject review = jsonElement.getAsJsonObject(); - JsonObject time = review.get("time").getAsJsonObject(); - - updates.add(new Update( - review.get("id").getAsString(), - review.get("resourceId").getAsString(), - review.get("title").getAsString(), - review.get("images").getAsString().split(";"), - review.get("description").getAsString(), - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()))); - } - - return updates; - } - - public PurchasesList fetchSpigotPurchases() { - JsonObject obj = makeRequest("data/spigot/purchases", ""); - PurchasesList purchases = new PurchasesList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return purchases; - } - } - if (!obj.has("data")) { - return purchases; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject purchase = jsonElement.getAsJsonObject(); - JsonObject time = purchase.get("time").getAsJsonObject(); - - Cost pluginCost = null; - if (purchase.has("cost")) { - JsonObject cost = purchase.get("cost").getAsJsonObject(); - pluginCost = new Cost(cost.get("currency").getAsString(), cost.get("value").getAsFloat()); - } - - purchases.add(new Purchase( - purchase.get("resourceId").getAsString(), - new User(purchase.get("user").getAsJsonObject()), - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()), - pluginCost)); - } - - return purchases; - } - - //Market - public ProfileCommentList fetchMarketProfileComments(String userid, boolean showAll) { - JsonObject obj = makeRequest("market/verifyUser", "&user=" + userid + "&showAll=" + showAll); - ProfileCommentList comments = new ProfileCommentList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return comments; - } - } - if (!obj.has("data")) { - return comments; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject comment = jsonElement.getAsJsonObject(); - - comments.add(new ProfileComment( - comment.get("commentId").getAsString(), - comment.get("userId").getAsString(), - comment.get("message").getAsString())); - } - - return comments; - } - - public ResourcesList fetchMarketResource() { - JsonObject obj = makeRequest("data/market/resources", ""); - ResourcesList resources = new ResourcesList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return resources; - } - } - if (!obj.has("data")) { - return resources; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject resource = jsonElement.getAsJsonObject(); - JsonObject time = resource.get("time").getAsJsonObject(); - - Cost pluginCost = null; - if (resource.has("cost")) { - JsonObject cost = resource.get("cost").getAsJsonObject(); - pluginCost = new Cost(cost.get("currency").getAsString(), cost.get("value").getAsFloat()); - } - - resources.add(new Resource( - resource.get("id").getAsString(), - resource.get("name").getAsString(), - resource.get("tagLine").getAsString(), - resource.get("category").getAsString(), - resource.get("version").getAsString(), - pluginCost, - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()) - , "market")); - } - - return resources; - } - - public ReviewsList fetchMarketReviews() { - JsonObject obj = makeRequest("data/market/reviews", ""); - ReviewsList reviews = new ReviewsList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return reviews; - } - } - if (!obj.has("data")) { - return reviews; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject review = jsonElement.getAsJsonObject(); - JsonObject time = review.get("time").getAsJsonObject(); - - reviews.add(new Review( - review.get("id").getAsString(), - review.get("resourceId").getAsString(), - new User(review.get("user").getAsJsonObject()), - review.get("text").getAsString(), - review.get("rating").getAsInt(), - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()))); - } - - return reviews; - } - - public UpdatesList fetchMarketUpdates() { - JsonObject obj = makeRequest("data/market/updates", ""); - UpdatesList updates = new UpdatesList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return updates; - } - } - if (!obj.has("data")) { - return updates; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject review = jsonElement.getAsJsonObject(); - JsonObject time = review.get("time").getAsJsonObject(); - - updates.add(new Update( - review.get("id").getAsString(), - review.get("resourceId").getAsString(), - review.get("title").getAsString(), - review.get("images").getAsString().split(";"), - review.get("description").getAsString(), - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()))); - } - - return updates; - } - - public PurchasesList fetchMarketPurchases() { - JsonObject obj = makeRequest("data/market/purchases", ""); - PurchasesList purchases = new PurchasesList(); - - if (obj.has("status")) { - if (obj.get("status").getAsString().equals("error")) { - TechDiscordBot.log(obj.get("msg").getAsString()); - return purchases; - } - } - if (!obj.has("data")) { - return purchases; - } - - JsonArray arr = obj.get("data").getAsJsonArray(); - - for (JsonElement jsonElement : arr) { - JsonObject review = jsonElement.getAsJsonObject(); - JsonObject time = review.get("time").getAsJsonObject(); - - Cost pluginCost = null; - if (review.has("cost")) { - JsonObject cost = review.get("cost").getAsJsonObject(); - pluginCost = new Cost(cost.get("currency").getAsString(), cost.get("value").getAsFloat()); - } - - purchases.add(new Purchase( - review.get("").getAsString(), - new User(review.get("user").getAsJsonObject()), - new Time(time.get("human").getAsString(), time.get("unix").getAsInt()), - pluginCost)); - } - - return purchases; - } - - public boolean stopAPI(){ - JsonObject obj = makeRequest("actions/stop", ""); - if (obj.has("Status")) { - return !obj.get("Status").getAsString().equals("Error"); - }else{ - return false; - } - } - - public boolean restartAPI() { - JsonObject obj = makeRequest("actions/restart", ""); - if (obj.has("Status")) { - return !obj.get("Status").getAsString().equals("Error"); - }else{ - return false; - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotApi.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotApi.java deleted file mode 100644 index b01d83ee..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/SpigotApi.java +++ /dev/null @@ -1,115 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc; - -import me.TechsCode.TechDiscordBot.spigotmc.data.APIWebStatus; -import me.TechsCode.TechDiscordBot.spigotmc.data.lists.*; - -import java.util.concurrent.TimeUnit; - -public class SpigotApi { - private static SpigotAPIManager spigotAPIClient; - private static long lastBotFetch; - - ResourcesList spigotResourcesList; - ReviewsList spigotReviewsList; - UpdatesList spigotUpdateList; - PurchasesList spigotPurchasesList; - - ResourcesList marketResourcesList; - ReviewsList marketReviewsList; - UpdatesList marketUpdateList; - PurchasesList marketPurchasesList; - - public SpigotApi(String url, String token) { - spigotAPIClient = new SpigotAPIManager(url, token); - - new Thread(() -> { - while (true) { - fetchNewData(); - - try { - Thread.sleep(TimeUnit.MINUTES.toMillis(5)); - } catch (InterruptedException ex) { - ex.printStackTrace(); - } - } - }).start(); - } - - public SpigotAPIManager getSpigotAPIManager() { - return spigotAPIClient; - } - - public void fetchNewData(){ - spigotResourcesList = spigotAPIClient.fetchSpigotResource(); - spigotReviewsList = spigotAPIClient.fetchSpigotReviews(); - spigotUpdateList = spigotAPIClient.fetchSpigotUpdates(); - spigotPurchasesList = spigotAPIClient.fetchSpigotPurchases(); - - marketResourcesList = spigotAPIClient.fetchMarketResource(); - marketReviewsList = spigotAPIClient.fetchMarketReviews(); - marketUpdateList = spigotAPIClient.fetchMarketUpdates(); - marketPurchasesList = spigotAPIClient.fetchMarketPurchases(); - - lastBotFetch = System.currentTimeMillis(); - } - - public long getLastBotFetch() { - return lastBotFetch; - } - - public boolean isOnline(){ - return spigotAPIClient.isOnline(); - } - - public APIWebStatus getStatus(){ - return spigotAPIClient.getStatus(); - } - - public ProfileCommentList getSpigotProfileComments(String userid, boolean showAll){ - return spigotAPIClient.fetchSpigotProfileComments(userid, showAll); - } - - public ResourcesList getSpigotResources() { - return spigotResourcesList; - } - - public ReviewsList getSpigotReviews() { - return spigotReviewsList; - } - - public UpdatesList getSpigotUpdates() { - return spigotUpdateList; - } - - public PurchasesList getSpigotPurchases() { - return spigotPurchasesList; - } - - public ProfileCommentList getMarketProfileComments(String userid, boolean showAll){ - return spigotAPIClient.fetchMarketProfileComments(userid, showAll); - } - - public ResourcesList getMarketResources() { - return marketResourcesList; - } - - public ReviewsList getMarketReviews() { - return marketReviewsList; - } - - public UpdatesList getMarketUpdates() { - return marketUpdateList; - } - - public PurchasesList getMarketPurchases() { - return marketPurchasesList; - } - - public boolean stopAPI(){ - return spigotAPIClient.restartAPI(); - } - - public boolean restartAPI(){ - return spigotAPIClient.restartAPI(); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIStatus.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIStatus.java deleted file mode 100644 index f2620857..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIStatus.java +++ /dev/null @@ -1,90 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.songoda.SongodaAPIClient; -import me.TechsCode.TechDiscordBot.spigotmc.SpigotAPIManager; - -import java.util.concurrent.TimeUnit; - -public enum APIStatus { - ONLINE("Online", "The api is online and running!", "low_priority"), - NOT_FETCHING("Not Fetching", "The api is online, but is not fetching new info!", "medium_priority"), - OFFLINE("Offline", "The api has no information. Something bad must've happened.", "high_priority"); - - private final String status, description, emojiName; - - APIStatus(String status, String description, String emojiName) { - this.status = status; - this.description = description; - this.emojiName = emojiName; - } - - public String getStatus() { - return status; - } - - public String getDescription() { - return description; - } - - public boolean isUsable() { - return this == ONLINE || this == NOT_FETCHING; - } - - public boolean isVerifyUsable() { - return this == ONLINE; - } - - public String getEmoji() { - return TechDiscordBot.getGuild().getEmotesByName(emojiName, true).get(0).getAsMention(); - } - - public static APIStatus getSpigotStatus(SpigotAPIManager client) { - APIStatus status; - - if(client.isOnline()){ - if(!client.getStatus().isSpigotFetching()) { - status = NOT_FETCHING; - } else { - status = ONLINE; - } - } else { - status = OFFLINE; - } - - return status; - } - - public static APIStatus getMarketStatus(SpigotAPIManager client) { - APIStatus status; - - if(client.isOnline()) { - if (!client.getStatus().isMarketFetching()) { - status = NOT_FETCHING; - } else { - status = ONLINE; - } - } else { - status = OFFLINE; - } - - return status; - } - - public static APIStatus getStatus(SongodaAPIClient client) { - APIStatus status; - - if(client.getRefreshTime() != 0L) { - if(client.getRefreshTime() + TimeUnit.HOURS.toMillis(1) < System.currentTimeMillis()) { - status = NOT_FETCHING; - } else { - status = ONLINE; - } - } else { - status = OFFLINE; - } - - return status; - } - -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIWebStatus.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIWebStatus.java deleted file mode 100644 index 8d50eeac..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/APIWebStatus.java +++ /dev/null @@ -1,42 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -public class APIWebStatus { - - private final String lastSpigotFetchDate, lastMarketFetchDate; - private final long lastSpigotFetch, lastMarketFetch; - private final boolean spigotFetching, marketFetching; - - public APIWebStatus(boolean spigotFetching, boolean marketFetching, long lastSpigotFetch, long lastMarketFetch, String lastSpigotFetchDate, String lastMarketFetchDate){ - this.spigotFetching = spigotFetching; - this.marketFetching = marketFetching; - this.lastSpigotFetch = lastSpigotFetch; - this.lastMarketFetch = lastMarketFetch; - this.lastSpigotFetchDate = lastSpigotFetchDate; - this.lastMarketFetchDate = lastMarketFetchDate; - } - - public boolean isMarketFetching() { - return marketFetching; - } - - public boolean isSpigotFetching() { - return spigotFetching; - } - - public long getLastSpigotFetch() { - return lastSpigotFetch; - } - - public String getLastSpigotFetchDate() { - return lastSpigotFetchDate; - } - - public long getLastMarketFetch() { - return lastMarketFetch; - } - - public String getLastMarketFetchDate() { - return lastMarketFetchDate; - } - -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Cost.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Cost.java deleted file mode 100644 index 200e6a60..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Cost.java +++ /dev/null @@ -1,43 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import com.google.common.base.Preconditions; -import com.google.gson.JsonObject; - -public class Cost { - - private final String currency; - private final float value; - - public Cost(JsonObject jsonObject){ - this.currency = jsonObject.get("currency").getAsString(); - this.value = jsonObject.get("value").getAsFloat(); - } - - public Cost(String combined){ - Preconditions.checkArgument(combined.contains(" "), "Invalid Combined String, is not seperated"); - - value = Float.parseFloat(combined.split(" ")[0]); - currency = combined.split(" ")[1]; - } - - public Cost(String currency, float value) { - this.currency = currency; - this.value = value; - } - - public String getCurrency() { - return currency; - } - - public float getValue() { - return value; - } - - public JsonObject toJsonObject(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("currency", currency); - jsonObject.addProperty("value", value); - - return jsonObject; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/ProfileComment.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/ProfileComment.java deleted file mode 100644 index 268e46e6..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/ProfileComment.java +++ /dev/null @@ -1,34 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import com.google.gson.JsonObject; - -public class ProfileComment { - private final String commentId, userId, message; - - public ProfileComment(String commentId, String userId, String message) { - this.commentId = commentId; - this.userId = userId; - this.message = message; - } - - public String getCommentId() { - return commentId; - } - - public String getUserId() { - return userId; - } - - public String getText() { - return message; - } - - public JsonObject getState() { - JsonObject comment = new JsonObject(); - comment.addProperty("commentId", commentId); - comment.addProperty("userId", userId); - comment.addProperty("message", message); - - return comment; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Purchase.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Purchase.java deleted file mode 100644 index 14c7e33b..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Purchase.java +++ /dev/null @@ -1,65 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import com.google.gson.JsonObject; -import me.TechsCode.TechDiscordBot.TechDiscordBot; - -import java.util.Objects; -import java.util.Optional; - -public class Purchase { - - private String resourceId; - private User user; - private Time time; - private Cost cost; - - public Purchase(String resourceId, User user, Time time, Cost cost) { - this.resourceId = resourceId; - this.user = user; - this.time = time; - this.cost = cost; - } - - public Purchase(JsonObject state) { - } - - public Resource getResource(){ - return TechDiscordBot.getSpigotAPI().getSpigotResources().id(resourceId).orElse(null); - } - - public User getUser() { - return user; - } - - public Time getTime() { - return time; - } - - public Optional<Cost> getCost() { - return Optional.ofNullable(cost); - } - - public boolean isPurchased(){ - return cost != null; - } - - public boolean isGifted(){ - return cost == null; - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Purchase purchase = (Purchase) o; - - return resourceId.equals(purchase.resourceId) && - user.getUserId().equals(purchase.user.getUserId()); - } - - @Override - public int hashCode() { - return Objects.hash(resourceId, user); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Resource.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Resource.java deleted file mode 100644 index ce4fcba5..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Resource.java +++ /dev/null @@ -1,110 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.spigotmc.data.lists.PurchasesList; -import me.TechsCode.TechDiscordBot.spigotmc.data.lists.ReviewsList; -import me.TechsCode.TechDiscordBot.spigotmc.data.lists.UpdatesList; - -import java.util.Objects; -import java.util.Optional; - -public class Resource { - - private final String id, name, tagLine, category, version, market; - private final Cost cost; - private final Time time; - - public Resource(String id, String name, String tagLine, String category, String version, Cost cost, Time time, String market) { - this.id = id; - this.name = name; - this.tagLine = tagLine; - this.category = category; - this.version = version; - this.cost = cost; - this.time = time; - this.market = market; - } - - public String getId() { - return id; - } - - public String getName() { - return name; - } - - public String getTagLine() { - return tagLine; - } - - public String getCategory() { - return category; - } - - public String getVersion() { - return version; - } - - public Optional<Cost> getCost() { - return Optional.ofNullable(cost); - } - - public Time getTime() { - return time; - } - - public boolean isPremium(){ - return cost != null; - } - - public boolean isFree(){ - return cost == null; - } - - public String getIcon() { - try { - int resourceId = Integer.parseInt(id); - return String.format("https://www.spigotmc.org/data/resource_icons/%d/%d.jpg", (int) Math.floor(resourceId / 1000d), resourceId); - } catch (NumberFormatException ex) { - return "https://static.spigotmc.org/styles/spigot/xenresource/resource_icon.png"; - } - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Resource resource = (Resource) o; - return id.equals(resource.id); - } - - @Override - public int hashCode() { - return Objects.hash(id); - } - - public UpdatesList getUpdates() { - if(market.equals("spigot")){ - return TechDiscordBot.getSpigotAPI().getSpigotUpdates().resource(id); - }else{ - return TechDiscordBot.getSpigotAPI().getMarketUpdates().resource(id); - } - } - - public ReviewsList getReviews() { - if(market.equals("spigot")){ - return TechDiscordBot.getSpigotAPI().getSpigotReviews().resource(id); - }else{ - return TechDiscordBot.getSpigotAPI().getMarketReviews().resource(id); - } - } - - public PurchasesList getPurchases() { - if(market.equals("spigot")){ - return TechDiscordBot.getSpigotAPI().getSpigotPurchases().resource(id); - }else{ - return TechDiscordBot.getSpigotAPI().getMarketPurchases().resource(id); - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Review.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Review.java deleted file mode 100644 index 37b85614..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Review.java +++ /dev/null @@ -1,61 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; - -import java.util.Objects; - -public class Review { - - private final String id, text, resourceId; - private final User user; - private final int rating; - private final Time time; - - public Review(String id, String resourceId, User user, String text, int rating, Time time) { - this.id = id; - this.resourceId = resourceId; - this.user = user; - this.text = text; - this.rating = rating; - this.time = time; - } - - public String getId() { - return id; - } - - public Resource getResource() { - return TechDiscordBot.getSpigotAPI().getSpigotResources().id(resourceId).orElse(null); - } - - public User getUser() { - return user; - } - - public String getText() { - return text; - } - - public int getRating() { - return rating; - } - - public Time getTime() { - return time; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Review review = (Review) o; - return id.equals(review.id) && - resourceId.equals(review.resourceId); - } - - @Override - public int hashCode() { - return Objects.hash(resourceId); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Time.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Time.java deleted file mode 100644 index 4dcef515..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Time.java +++ /dev/null @@ -1,63 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import com.google.common.base.Preconditions; -import com.google.gson.JsonObject; - -import java.time.Month; -import java.util.Arrays; -import java.util.Calendar; - -public class Time { - - private final String humanTime; - private final long unixTime; - - public Time(JsonObject jsonObject){ - this.humanTime = jsonObject.get("human").getAsString(); - this.unixTime = jsonObject.get("unix").getAsLong(); - } - - public Time(String humanTime, long unixTime) { - this.humanTime = humanTime; - this.unixTime = unixTime; - } - - public Time(String humanTime){ - Preconditions.checkArgument(humanTime.length() > 5, "Invalid Time Value (Too short)"); - this.humanTime = humanTime; - - String date = humanTime.split(" at ")[0].replace(",", ""); - String time = humanTime.split(" at ")[1]; - - String monthString = date.split(" ")[0].toLowerCase(); - int month = Arrays.stream(Month.values()).filter(x -> x.name().toLowerCase().startsWith(monthString)).findFirst().get().getValue(); - int day = Integer.parseInt(date.split(" ")[1]); - int year = Integer.parseInt(date.split(" ")[2]); - - boolean pm = date.endsWith("PM"); - String substring = time.substring(0, time.length() - 3); - - int hour = Integer.parseInt(substring.split(":")[0]); - int minute = Integer.parseInt(substring.split(":")[1]); - - Calendar c = Calendar.getInstance(); - c.set(year, month - 1, day, pm ? hour + 12 : hour, minute); - - this.unixTime = c.getTimeInMillis(); - } - - public String getHumanTime() { - return humanTime; - } - - public long getUnixTime() { - return unixTime; - } - - public JsonObject toJsonObject(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("human", humanTime); - jsonObject.addProperty("unix", unixTime); - return jsonObject; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Update.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Update.java deleted file mode 100644 index 3aa7a646..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/Update.java +++ /dev/null @@ -1,67 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; - -import java.util.Objects; - -public class Update { - - private final String id; - private final String resourceId; - private final String title; - private final String[] images; - private final String description; - private final Time time; - - public Update(String id, String resourceId, String title, String[] images, String description, Time time) { - this.id = id; - this.resourceId = resourceId; - this.title = title; - this.images = images; - this.description = description; - this.time = time; - } - - public Resource getResource(){ - return TechDiscordBot.getSpigotAPI().getSpigotResources().id(resourceId).orElse(null); - } - - public String getId() { - return id; - } - - public String getResourceId() { - return resourceId; - } - - public String getTitle() { - return title; - } - - public String[] getImages() { - return images; - } - - public String getDescription() { - return description; - } - - public Time getTime() { - return time; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Update update = (Update) o; - return id.equals(update.id) && - resourceId.equals(update.resourceId); - } - - @Override - public int hashCode() { - return Objects.hash(id, resourceId); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/User.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/User.java deleted file mode 100644 index 191f9543..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/User.java +++ /dev/null @@ -1,40 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data; - -import com.google.gson.JsonObject; - -public class User { - - private final String userId, username, avatar; - - public User(JsonObject jsonObject){ - this.userId = jsonObject.get("userId").getAsString(); - this.username = jsonObject.get("username").getAsString(); - this.avatar = jsonObject.get("avatar").getAsString(); - } - - public User(String userId, String username, String avatar) { - this.userId = userId; - this.username = username; - this.avatar = avatar; - } - - public String getUserId() { - return userId; - } - - public String getUsername() { - return username; - } - - public String getAvatar() { - return avatar; - } - - public JsonObject toJsonObject(){ - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("userId", userId); - jsonObject.addProperty("username", username); - jsonObject.addProperty("avatar", avatar); - return jsonObject; - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ProfileCommentList.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ProfileCommentList.java deleted file mode 100644 index 3964d43d..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ProfileCommentList.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data.lists; - -import me.TechsCode.TechDiscordBot.spigotmc.data.ProfileComment; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.stream.Collectors; - -public class ProfileCommentList extends ArrayList<ProfileComment> { - - public ProfileCommentList(int initialCapacity) { - super(initialCapacity); - } - - public ProfileCommentList() {} - - public ProfileCommentList(Collection<? extends ProfileComment> c) { - super(c); - } - - public ProfileCommentList userId(String userId){ - return stream().filter(ProfileComment -> ProfileComment.getUserId().equals(userId)).collect(Collectors.toCollection(ProfileCommentList::new)); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/PurchasesList.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/PurchasesList.java deleted file mode 100644 index adac92b4..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/PurchasesList.java +++ /dev/null @@ -1,36 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data.lists; - -import me.TechsCode.TechDiscordBot.spigotmc.data.Purchase; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.stream.Collectors; - -public class PurchasesList extends ArrayList<Purchase> { - - public PurchasesList(int initialCapacity) { - super(initialCapacity); - } - - public PurchasesList() {} - - public PurchasesList(Collection<? extends Purchase> c) { - super(c); - } - - public PurchasesList userId(String userId){ - return stream().filter(purchase -> purchase.getUser().getUserId().equals(userId)).collect(Collectors.toCollection(PurchasesList::new)); - } - - public PurchasesList username(String username){ - return stream().filter(purchase -> purchase.getUser().getUsername().equalsIgnoreCase(username)).collect(Collectors.toCollection(PurchasesList::new)); - } - - public PurchasesList resource(String resourceId){ - return stream().filter(purchase -> purchase.getResource().getId().equals(resourceId)).collect(Collectors.toCollection(PurchasesList::new)); - } - - public PurchasesList gifted(){ - return stream().filter(Purchase::isGifted).collect(Collectors.toCollection(PurchasesList::new)); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ResourcesList.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ResourcesList.java deleted file mode 100644 index d92bdd70..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ResourcesList.java +++ /dev/null @@ -1,37 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data.lists; - -import me.TechsCode.TechDiscordBot.spigotmc.data.Resource; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Optional; -import java.util.stream.Collectors; - -public class ResourcesList extends ArrayList<Resource> { - - public ResourcesList(int initialCapacity) { - super(initialCapacity); - } - - public ResourcesList() {} - - public ResourcesList(Collection<? extends Resource> c) { - super(c); - } - - public Optional<Resource> id(String id){ - return stream().filter(resource -> resource.getId().equals(id)).findFirst(); - } - - public Optional<Resource> name(String name){ - return stream().filter(resource -> resource.getName().equalsIgnoreCase(name)).findFirst(); - } - - public ResourcesList free(){ - return stream().filter(Resource::isFree).collect(Collectors.toCollection(ResourcesList::new)); - } - - public ResourcesList premium(){ - return stream().filter(Resource::isPremium).collect(Collectors.toCollection(ResourcesList::new)); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ReviewsList.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ReviewsList.java deleted file mode 100644 index efe6a56e..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/ReviewsList.java +++ /dev/null @@ -1,32 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data.lists; - -import me.TechsCode.TechDiscordBot.spigotmc.data.Review; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.stream.Collectors; - -public class ReviewsList extends ArrayList<Review> { - - public ReviewsList(int initialCapacity) { - super(initialCapacity); - } - - public ReviewsList() {} - - public ReviewsList(Collection<? extends Review> c) { - super(c); - } - - public ReviewsList userId(String userId){ - return stream().filter(review -> review.getUser().getUserId().equals(userId)).collect(Collectors.toCollection(ReviewsList::new)); - } - - public ReviewsList username(String username){ - return stream().filter(review -> review.getUser().getUsername().equalsIgnoreCase(username)).collect(Collectors.toCollection(ReviewsList::new)); - } - - public ReviewsList resource(String resourceId){ - return stream().filter(review -> review.getResource().getId().equals(resourceId)).collect(Collectors.toCollection(ReviewsList::new)); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/UpdatesList.java b/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/UpdatesList.java deleted file mode 100644 index 8d3581fa..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/spigotmc/data/lists/UpdatesList.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.TechsCode.TechDiscordBot.spigotmc.data.lists; - -import me.TechsCode.TechDiscordBot.spigotmc.data.Update; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.stream.Collectors; - -public class UpdatesList extends ArrayList<Update> { - - public UpdatesList(int initialCapacity) { - super(initialCapacity); - } - - public UpdatesList() {} - - public UpdatesList(Collection<? extends Update> c) { - super(c); - } - - public UpdatesList resource(String resourceId){ - return stream().filter(update -> update.getResource().getId().equals(resourceId)).collect(Collectors.toCollection(UpdatesList::new)); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscript.java b/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscript.java index 2e4833ce..8e5d6c03 100644 --- a/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscript.java +++ b/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscript.java @@ -1,13 +1,13 @@ -package me.TechsCode.TechDiscordBot.transcripts; +package me.techscode.techdiscordbot.transcripts; import com.google.gson.JsonArray; import com.google.gson.JsonObject; -import me.TechsCode.TechDiscordBot.module.modules.TicketModule; -import me.TechsCode.TechDiscordBot.util.PasswordGenerator; +import com.greazi.discordbotfoundation.utils.RandomGenerator; +import me.techscode.techdiscordbot.database.Database; import net.dv8tion.jda.api.entities.Member; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.entities.Role; -import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.entities.channel.concrete.TextChannel; import java.util.*; import java.util.function.Consumer; @@ -32,7 +32,7 @@ public TicketTranscript(TextChannel channel, TicketTranscriptOptions options) { this.fetchAll = options.getMessagesAmount() == -1; this.id = UUID.randomUUID().toString(); - this.password = PasswordGenerator.generateRandomPassword(10); + this.password = RandomGenerator.string(10); } public static TicketTranscript buildTranscript(TextChannel channel, TicketTranscriptOptions options) { @@ -58,7 +58,7 @@ public void build(Consumer<JsonObject> consumer) { object.addProperty("password", this.password); object.add("members", buildMembers(memberMessages)); - object.add("creator", buildMember(TicketModule.getMemberFromTicket(channel))); + object.add("creator", buildMember(Database.TICKETS.get(channel.getIdLong()).get(0).getMember().getDiscordMember() == null ? channel.getGuild().getMemberById("619084935655063552") : Database.TICKETS.get(channel.getIdLong()).get(0).getMember().getDiscordMember())); object.add("messages", array); consumer.accept(object); diff --git a/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptMessageType.java b/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptMessageType.java index 359bd67c..4ed4c14d 100644 --- a/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptMessageType.java +++ b/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptMessageType.java @@ -1,4 +1,4 @@ -package me.TechsCode.TechDiscordBot.transcripts; +package me.techscode.techdiscordbot.transcripts; public enum TicketTranscriptMessageType { diff --git a/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptOptions.java b/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptOptions.java index 0e479732..fcd58421 100644 --- a/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptOptions.java +++ b/src/main/java/me/TechsCode/TechDiscordBot/transcripts/TicketTranscriptOptions.java @@ -1,4 +1,4 @@ -package me.TechsCode.TechDiscordBot.transcripts; +package me.techscode.techdiscordbot.transcripts; public class TicketTranscriptOptions { diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/Config.java b/src/main/java/me/TechsCode/TechDiscordBot/util/Config.java deleted file mode 100644 index febf9080..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/Config.java +++ /dev/null @@ -1,113 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import org.apache.commons.io.FileUtils; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; - -public class Config { - - private static Config instance; - - public static Config getInstance(){ - if(instance == null){ - instance = new Config(); - } - - return instance; - } - - private JsonObject root; - - private Config() { - File file = new File("config.json"); - - if(!file.exists()){ - try { - InputStream src = Config.class.getResourceAsStream("/config.json"); - Files.copy(src, Paths.get(file.toURI()), StandardCopyOption.REPLACE_EXISTING); - } catch (IOException e) { - e.printStackTrace(); - } - } - - try { - String json = FileUtils.readFileToString(file, StandardCharsets.UTF_8); - - JsonParser jsonParser = new JsonParser(); - root = (JsonObject) jsonParser.parse(json); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public boolean isConfigured(){ - return !getToken().equals("") || - !getApiToken().equals("") || - !getSongodaApiToken().equals("") || - !getMySqlHost().equals("") || - !getMySqlPort().equals("") || - !getMySqlDatabase().equals("") || - !getMySqlUsername().equals("") || - !getMySqlPassword().equals("") || - !getGithubToken().equals("") || - !getSpigotApiUrl().equals(""); - } - - public String getToken(){ - return root.get("token").getAsString(); - } - - public String getApiToken(){ - return root.get("apiToken").getAsString(); - } - - public String getSongodaApiToken(){ - return root.get("songodaApiToken").getAsString(); - } - - public String getMySqlHost(){ - return root.get("mySQL_host").getAsString(); - } - - public String getMySqlPort(){ - return root.get("mySQL_port").getAsString(); - } - - public String getMySqlDatabase(){ - return root.get("mySQL_database").getAsString(); - } - - public String getMySqlUsername(){ - return root.get("mySQL_username").getAsString(); - } - - public String getMySqlPassword(){ - return root.get("mySQL_password").getAsString(); - } - - public String getGithubToken(){ - return root.get("githubToken").getAsString(); - } - - public String getPteroUrl(){ - return root.get("pterodactylUrl").getAsString(); - } - - public String getPteroClientToken(){ - return root.get("pterodactylClientToken").getAsString(); - } - - public String getPteroApiToken(){ - return root.get("pterodactylApiToken").getAsString(); - } - - public String getSpigotApiUrl(){return root.get("spigotApiUrl").getAsString();} -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/ConsoleColor.java b/src/main/java/me/TechsCode/TechDiscordBot/util/ConsoleColor.java deleted file mode 100644 index 75817fae..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/ConsoleColor.java +++ /dev/null @@ -1,70 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -public class ConsoleColor { - - public static final String RESET = "\033[0m"; // Text Reset - - public static final String BLACK = "\033[0;30m"; // BLACK - public static final String RED = "\033[0;31m"; // RED - public static final String GREEN = "\033[0;32m"; // GREEN - public static final String YELLOW = "\033[0;33m"; // YELLOW - public static final String BLUE = "\033[0;34m"; // BLUE - public static final String PURPLE = "\033[0;35m"; // PURPLE - public static final String CYAN = "\033[0;36m"; // CYAN - public static final String WHITE = "\033[0;37m"; // WHITE - - public static final String BLACK_BOLD = "\033[1;30m"; // BLACK - public static final String RED_BOLD = "\033[1;31m"; // RED - public static final String GREEN_BOLD = "\033[1;32m"; // GREEN - public static final String YELLOW_BOLD = "\033[1;33m"; // YELLOW - public static final String BLUE_BOLD = "\033[1;34m"; // BLUE - public static final String PURPLE_BOLD = "\033[1;35m"; // PURPLE - public static final String CYAN_BOLD = "\033[1;36m"; // CYAN - public static final String WHITE_BOLD = "\033[1;37m"; // WHITE - - public static final String BLACK_UNDERLINED = "\033[4;30m"; // BLACK - public static final String RED_UNDERLINED = "\033[4;31m"; // RED - public static final String GREEN_UNDERLINED = "\033[4;32m"; // GREEN - public static final String YELLOW_UNDERLINED = "\033[4;33m"; // YELLOW - public static final String BLUE_UNDERLINED = "\033[4;34m"; // BLUE - public static final String PURPLE_UNDERLINED = "\033[4;35m"; // PURPLE - public static final String CYAN_UNDERLINED = "\033[4;36m"; // CYAN - public static final String WHITE_UNDERLINED = "\033[4;37m"; // WHITE - - public static final String BLACK_BACKGROUND = "\033[40m"; // BLACK - public static final String RED_BACKGROUND = "\033[41m"; // RED - public static final String GREEN_BACKGROUND = "\033[42m"; // GREEN - public static final String YELLOW_BACKGROUND = "\033[43m"; // YELLOW - public static final String BLUE_BACKGROUND = "\033[44m"; // BLUE - public static final String PURPLE_BACKGROUND = "\033[45m"; // PURPLE - public static final String CYAN_BACKGROUND = "\033[46m"; // CYAN - public static final String WHITE_BACKGROUND = "\033[47m"; // WHITE - - public static final String BLACK_BRIGHT = "\033[0;90m"; // BLACK - public static final String RED_BRIGHT = "\033[0;91m"; // RED - public static final String GREEN_BRIGHT = "\033[0;92m"; // GREEN - public static final String YELLOW_BRIGHT = "\033[0;93m"; // YELLOW - public static final String BLUE_BRIGHT = "\033[0;94m"; // BLUE - public static final String PURPLE_BRIGHT = "\033[0;95m"; // PURPLE - public static final String CYAN_BRIGHT = "\033[0;96m"; // CYAN - public static final String WHITE_BRIGHT = "\033[0;97m"; // WHITE - - public static final String BLACK_BOLD_BRIGHT = "\033[1;90m"; // BLACK - public static final String RED_BOLD_BRIGHT = "\033[1;91m"; // RED - public static final String GREEN_BOLD_BRIGHT = "\033[1;92m"; // GREEN - public static final String YELLOW_BOLD_BRIGHT = "\033[1;93m";// YELLOW - public static final String BLUE_BOLD_BRIGHT = "\033[1;94m"; // BLUE - public static final String PURPLE_BOLD_BRIGHT = "\033[1;95m";// PURPLE - public static final String CYAN_BOLD_BRIGHT = "\033[1;96m"; // CYAN - public static final String WHITE_BOLD_BRIGHT = "\033[1;97m"; // WHITE - - public static final String BLACK_BACKGROUND_BRIGHT = "\033[0;100m";// BLACK - public static final String RED_BACKGROUND_BRIGHT = "\033[0;101m";// RED - public static final String GREEN_BACKGROUND_BRIGHT = "\033[0;102m";// GREEN - public static final String YELLOW_BACKGROUND_BRIGHT = "\033[0;103m";// YELLOW - public static final String BLUE_BACKGROUND_BRIGHT = "\033[0;104m";// BLUE - public static final String PURPLE_BACKGROUND_BRIGHT = "\033[0;105m"; // PURPLE - public static final String CYAN_BACKGROUND_BRIGHT = "\033[0;106m"; // CYAN - public static final String WHITE_BACKGROUND_BRIGHT = "\033[0;107m"; // WHITE - -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/PasswordGenerator.java b/src/main/java/me/TechsCode/TechDiscordBot/util/PasswordGenerator.java deleted file mode 100644 index e4a40d7d..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/PasswordGenerator.java +++ /dev/null @@ -1,42 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class PasswordGenerator { - - private static final String CHAR_LOWER = "abcdefghijklmnopqrstuvwxyz"; - private static final String CHAR_UPPER = CHAR_LOWER.toUpperCase(); - private static final String NUMBER = "0123456789"; - private static final String OTHER_CHAR = "!@#$%&*()_+-=[]?"; - private static final String OTHER_CHARS_2 = "!@*()_"; - - private static final String PASSWORD_ALLOW_BASE = CHAR_LOWER + CHAR_UPPER + NUMBER + OTHER_CHARS_2; - private static final String PASSWORD_ALLOW_BASE_SHUFFLE = shuffleString(PASSWORD_ALLOW_BASE); - private static final String PASSWORD_ALLOW = PASSWORD_ALLOW_BASE_SHUFFLE; - - private static final SecureRandom random = new SecureRandom(); - - public static String generateRandomPassword(int length) { - if (length < 1) - throw new IllegalArgumentException(); - - StringBuilder sb = new StringBuilder(length); - for (int i = 0; i < length; i++) { - int rndCharAt = random.nextInt(PASSWORD_ALLOW.length()); - char rndChar = PASSWORD_ALLOW.charAt(rndCharAt); - sb.append(rndChar); - } - - return sb.toString(); - } - - public static String shuffleString(String string) { - List<String> letters = Arrays.asList(string.split("")); - Collections.shuffle(letters); - - return String.join("", letters); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/Plugin.java b/src/main/java/me/TechsCode/TechDiscordBot/util/Plugin.java deleted file mode 100644 index 03a3e2e7..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/Plugin.java +++ /dev/null @@ -1,212 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import me.TechsCode.TechDiscordBot.mysql.storage.Verification; -import me.TechsCode.TechDiscordBot.spigotmc.data.Resource; -import me.TechsCode.TechDiscordBot.spigotmc.data.Update; -import me.TechsCode.TechDiscordBot.spigotmc.data.lists.PurchasesList; -import net.dv8tion.jda.api.entities.*; - -import java.awt.*; -import java.io.File; -import java.net.URL; -import java.nio.file.Paths; -import java.util.List; -import java.util.*; -import java.util.stream.Collectors; - -public enum Plugin { - - ULTRA_PERMISSIONS("Ultra Permissions", PluginMarketplace.of("42678", "150", "19028", "1201"), "416194311080771596", "330053303050436608", new Color(0,235,229), "UltraPermissions", "https://www.spigotmc.org/data/resource_icons/42/42678.jpg?75455775"), - ULTRA_CUSTOMIZER("Ultra Customizer", PluginMarketplace.of("49330", "151", "19029", "1203"), "416194287567372298", "380133603683860480", new Color(184, 103, 243), "UltraCustomizer", "https://www.spigotmc.org/data/resource_icons/49/49330.jpg?575757457475"), - ULTRA_REGIONS("Ultra Regions", PluginMarketplace.of("58317", "152", "19031", "1205"), "465975554101739520", "465975795433734155", new Color(57, 135, 153), "UltraRegions", "https://www.spigotmc.org/data/resource_icons/58/58317.jpg?5775757457"), - ULTRA_PUNISHMENTS("Ultra Punishments", PluginMarketplace.of("63511", "154", "19030", "1204"), "531255363505487872", "531251918291599401", new Color(247, 119, 39), "UltraPunishments", "https://www.spigotmc.org/data/resource_icons/63/63511.jpg?1597561836"), - INSANE_SHOPS("Insane Shops", PluginMarketplace.of("67352", "153", "19032", "1202"), "531255363505487872", "576813543698202624", new Color(114, 185, 77), "InsaneShops", "https://www.spigotmc.org/data/resource_icons/67/67352.jpg?1597561788"), - ULTRA_ECONOMY("Ultra Economy", PluginMarketplace.of("83374", "639", "19033", "1206"), "749034791936196649", "737773631198986240", new Color(255, 198, 10), "UltraEconomy", "https://www.spigotmc.org/data/resource_icons/83/83374.jpg?1598896895"), - ULTRA_SCOREBOARDS("Ultra Scoreboards", PluginMarketplace.of("93726", "643", "20697", "1401"), "811397836616630352", "858052621574078474", new Color(131, 52, 235), "UltraScoreboards", "https://www.spigotmc.org/data/resource_icons/93/93726.jpg?1624925787"), - ULTRA_MOTD("Ultra Motd", PluginMarketplace.of("100883", "", "", ""), "936284238519599104", "931264562995540038", new Color(85, 144, 217), "UltraMotd", "https://www.spigotmc.org/data/resource_icons/100/100883.jpg?1647948784"); - - private final PluginMarketplace pluginMarketplace; - private final String channelId, roleName, roleId, emojiName, logo; - private final Color color; - - Plugin(String roleName, PluginMarketplace pluginMarketplace, String roleId, String channelId, Color color, String emojiName, String logo) { - this.roleName = roleName; - this.pluginMarketplace = pluginMarketplace; - this.channelId = channelId; - this.roleId = roleId; - this.color = color; - this.emojiName = emojiName; - this.logo = logo; - } - - public String getResourceId() { - return pluginMarketplace.getSpigotResourceId(); - } - - public PluginMarketplace getPluginMarketplace() { - return pluginMarketplace; - } - - public String getChannelId() { - return channelId; - } - - public Optional<TextChannel> getChannel() { - return Optional.ofNullable(TechDiscordBot.getJDA().getTextChannelById(getChannelId())); - } - - public String getRoleId() { - return roleId; - } - - public Role getRole(Guild guild) { - return guild.getRoleById(roleId); - } - - public Color getColor() { - return color; - } - - public String getDescription() { - return TechDiscordBot.getSpigotAPI().getSpigotResources().id(getResourceId()).get().getTagLine(); - } - - public String getResourceLogo() { - return logo; - } - - public String getEmojiName() { - return emojiName; - } - - public Emote getEmoji() { - return TechDiscordBot.getJDA().getEmotesByName(getEmojiName(), false).get(0); - } - - public String getRoleName() { - return roleName; - } - - public String getWiki() { - return "https://" + getRoleName().toLowerCase().replace(" ", "") + ".com/wiki"; - } - - public boolean hasWiki() { - return true; - } - - public String getBanner() { - return "https://" + getRoleName().toLowerCase().replace(" ", "") + ".com/banner.png"; - } - - public File getBannerAsFile() { - String resourceName = getResource().getName().replaceAll(" ", ""); - File bFile = new File("banners/"+resourceName+".png"); - - if(bFile.exists()) - return bFile; - - try{ - URL url = new URL(getBanner()); - return Paths.get(url.toURI()).toFile(); - }catch (Exception ignored){} - - return null; - } - - private Dimension getScaledDimension(Dimension imageSize, Dimension boundary) { - double widthRatio = boundary.getWidth() / imageSize.getWidth(); - double heightRatio = boundary.getHeight() / imageSize.getHeight(); - double ratio = Math.min(widthRatio, heightRatio); - - return new Dimension((int) (imageSize.width * ratio), - (int) (imageSize.height * ratio)); - } - - public Resource getResource() { - return TechDiscordBot.getSpigotAPI().getSpigotResources().id(getResourceId()).get(); - } - - public Update getLatestUpdate() { - return TechDiscordBot.getSpigotAPI().getSpigotUpdates().resource(getResourceId()).stream().findFirst().orElse(null); - } - - public static List<Plugin> allWithWiki() { - return Arrays.stream(Plugin.values()).filter(Plugin::hasWiki).collect(Collectors.toList()); - } - - public static String getEmotesByList(List<String> plugins) { - String sb = plugins.stream().map(Plugin::byRoleName).filter(Objects::nonNull).map(plugin -> plugin.getEmoji().getAsMention() + " ").collect(Collectors.joining()); - - if(sb.length() < 4) return ""; - return sb.substring(0, sb.length() - 1); - } - - public static boolean isPluginChannel(TextChannel channel) { - return Arrays.stream(Plugin.values()).anyMatch(p -> channel.getId().equals(p.getChannelId())); - } - - public static Plugin byChannel(TextChannel channel) { - return Arrays.stream(Plugin.values()).filter(p -> channel.getId().equals(p.getChannelId())).findFirst().orElse(null); - } - - public static Plugin byRoleName(String roleName) { - return Arrays.stream(Plugin.values()).filter(p -> p.getRoleName().equals(roleName)).findFirst().orElse(null); - } - - public static Plugin byEmojiName(String emojiName) { - return Arrays.stream(Plugin.values()).filter(p -> p.getEmojiName().equals(emojiName)).findFirst().orElse(null); - } - - public static Plugin byEmote(Emote emote) { - return Arrays.stream(values()).filter(e -> emote.getId().equals(e.getEmoji().getId())).findFirst().orElse(null); - } - - public static List<Plugin> fromUserUsingRoles(Member member) { - return member.getRoles().stream().filter(role -> Plugin.byRoleName(role.getName()) != null).map(role -> Plugin.byRoleName(role.getName())).collect(Collectors.toList()); - } - - public static Plugin fromId(String resourceId) { - return Arrays.stream(values()).filter(all -> all.getResourceId().equals(resourceId)).findFirst().orElse(null); - } - - public static String getMembersPluginsinEmojis(Member member) { - return getMembersPluginsinEmojis(member, "None"); - } - - public static String getMembersPluginsinEmojis(Member member, String defaultResponse) { - List<Plugin> plugins = Plugin.fromUser(member); - StringBuilder sb = new StringBuilder(); - int i = 0; - for (Plugin p : plugins) { - if (i != 0) sb.append(" "); - sb.append(p.getEmoji().getAsMention()); - i++; - } - if(i == 0) sb.append(defaultResponse); - return sb.toString(); - } - - public static List<Plugin> fromUser(Member member) { - try { - Verification verification = TechDiscordBot.getStorage().retrieveVerificationWithDiscord(member.getUser().getId()); - - PurchasesList pc = null; - try { - pc = TechDiscordBot.getSpigotAPI().getSpigotPurchases().userId(verification.getUserId()); - } catch (NullPointerException ignored) { - TechDiscordBot.log(ConsoleColor.RED + "Could not find any SpigotMC plugins for " + member.getEffectiveName() + "#" + member.getUser().getDiscriminator()); - } - - List<Plugin> plugins = new ArrayList<>(); - if(pc != null) plugins = pc.stream().map(purchase -> fromId(purchase.getResource().getId())).collect(Collectors.toList()); - - return plugins; - } catch (NullPointerException ex) { - TechDiscordBot.log(ConsoleColor.RED + "Error:"); - ex.printStackTrace(); - return new ArrayList<>(); - } - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/PluginMarketplace.java b/src/main/java/me/TechsCode/TechDiscordBot/util/PluginMarketplace.java deleted file mode 100644 index e66f402f..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/PluginMarketplace.java +++ /dev/null @@ -1,79 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -public class PluginMarketplace { - - private final String spigotRId, songodaRId, mcMarketRId, polymartRId; - - private PluginMarketplace(String spigotRId, String songodaRId, String mcMarketRId, String polymartRId) { - this.spigotRId = spigotRId; - this.songodaRId = songodaRId; - this.mcMarketRId = mcMarketRId; - this.polymartRId = polymartRId; - } - - public static PluginMarketplace of(String spigotRId, String songodaRId, String mcMarketRId, String polymartRId) { - return new PluginMarketplace(spigotRId, songodaRId, mcMarketRId, polymartRId); - } - - public String getSpigotResourceId() { - return spigotRId; - } - - public String getSpigotResourceUrl() { - return "https://www.spigotmc.org/resources/" + spigotRId; - } - - public String getSongodaResourceId() { - return songodaRId; - } - - public String getSongodaResourceUrl() { - return "https://songoda.com/marketplace/product/" + songodaRId; - } - - public String getMcMarketResourceId() { - return mcMarketRId; - } - - public String getMcMarketResourceUrl() { - return "https://www.mc-market.org/resources/" + mcMarketRId; - } - - public String getPolymartResourceId() { - return polymartRId; - } - - public String getPolymartResourceUrl() { - return "https://polymart.org/resource/" + polymartRId; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - if(spigotRId != null) - sb.append("[SpigotMC](").append(getSpigotResourceUrl()).append(")"); - - if(songodaRId != null) { - appendNotEmpty(sb); - sb.append("[Songoda](").append(getSongodaResourceUrl()).append(")"); - } - - if(mcMarketRId != null) { - appendNotEmpty(sb); - sb.append("[MC-Market](").append(getMcMarketResourceUrl()).append(")"); - } - - if(polymartRId != null) { - appendNotEmpty(sb); - sb.append("[Polymart](").append(getPolymartResourceUrl()).append(")"); - } - - return sb.toString(); - } - - private void appendNotEmpty(StringBuilder sb) { - if(!sb.toString().isEmpty()) - sb.append(" **-** "); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/ProjectUtil.java b/src/main/java/me/TechsCode/TechDiscordBot/util/ProjectUtil.java deleted file mode 100644 index 8e6d40fc..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/ProjectUtil.java +++ /dev/null @@ -1,61 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -import java.io.IOException; -import java.net.URL; -import java.security.CodeSource; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Objects; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; - -public class ProjectUtil { - - public static String[] getFiles() { - ArrayList<String> names = new ArrayList<>(); - try { - CodeSource src = ProjectUtil.class.getProtectionDomain().getCodeSource(); - if (src != null) { - URL jar = src.getLocation(); - ZipInputStream zip = new ZipInputStream(jar.openStream()); - while(true) { - ZipEntry e = zip.getNextEntry(); - if (e == null) break; - names.add(e.getName()); - } - } - } catch (IOException e) { - e.printStackTrace(); - } - return names.toArray(new String[0]); - } - - public static Class<?>[] getClasses(String prefix) { - return Arrays.stream(getFiles()) - .filter(fileName -> fileName.endsWith(".class")) - .map(className -> className.replace("/", ".").replace(".class", "")) - .filter(fileName -> fileName.startsWith(prefix)) - .map(className -> { - try { - return Class.forName(className); - } catch (ClassNotFoundException e) { - e.printStackTrace(); - return null; - } - }) - .filter(Objects::nonNull) - .toArray(Class[]::new); - } - - public static String removeFront(String s, int am) { - return s.substring(am); - } - - public static String removeEnd(String s, int am) { - return s.substring(0, s.length() - am); - } - - public static String removeBoth(String s, int am) { - return s.substring(am, s.length() - am); - } -} \ No newline at end of file diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/PterodactylAPI.java b/src/main/java/me/TechsCode/TechDiscordBot/util/PterodactylAPI.java deleted file mode 100644 index 7c44c43c..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/PterodactylAPI.java +++ /dev/null @@ -1,49 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -import com.mattmalec.pterodactyl4j.PteroBuilder; -import com.mattmalec.pterodactyl4j.application.entities.PteroApplication; -import com.mattmalec.pterodactyl4j.client.entities.ClientServer; -import com.mattmalec.pterodactyl4j.client.entities.PteroClient; - -public class PterodactylAPI { - private PteroClient client; - private PteroApplication api; - - public void setup(String url, String clientToken, String appToken){ - if(!clientToken.isEmpty()){ - client = PteroBuilder.createClient(url, clientToken); - } - if(!appToken.isEmpty()){ - api = PteroBuilder.createApplication(url, appToken); - } - } - - public boolean clientConfigured(){ - return client != null; - } - - public boolean apiConfigured(){ - return api != null; - } - - public void startServer(String serverId){ - if(!clientConfigured()) return; - client.retrieveServerByIdentifier(serverId).flatMap(ClientServer::start).executeAsync(); - } - - public void stopServer(String serverId){ - if(!clientConfigured()) return; - client.retrieveServerByIdentifier(serverId).flatMap(ClientServer::stop).executeAsync(); - } - - public void restartServer(String serverId){ - if(!clientConfigured()) return; - client.retrieveServerByIdentifier(serverId).flatMap(ClientServer::restart).executeAsync(); - } - - public void killServer(String serverId) { - if(!clientConfigured()) return; - client.retrieveServerByIdentifier(serverId).flatMap(ClientServer::kill).executeAsync(); - } - -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/util/TechEmbedBuilder.java b/src/main/java/me/TechsCode/TechDiscordBot/util/TechEmbedBuilder.java deleted file mode 100644 index d3b6392f..00000000 --- a/src/main/java/me/TechsCode/TechDiscordBot/util/TechEmbedBuilder.java +++ /dev/null @@ -1,210 +0,0 @@ -package me.TechsCode.TechDiscordBot.util; - -import me.TechsCode.TechDiscordBot.TechDiscordBot; -import net.dv8tion.jda.api.EmbedBuilder; -import net.dv8tion.jda.api.entities.Member; -import net.dv8tion.jda.api.entities.Message; -import net.dv8tion.jda.api.entities.TextChannel; -import net.dv8tion.jda.api.entities.User; -import net.dv8tion.jda.api.exceptions.ErrorResponseException; - -import java.awt.*; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; -import java.util.function.Consumer; - -public class TechEmbedBuilder extends EmbedBuilder { - - public TechEmbedBuilder() { - color(new Color(81, 153, 226)); - } - - public TechEmbedBuilder(String title) { - if(title != null) - setAuthor(title, "https://techscode.com", "https://i.imgur.com/nnegGEV.png"); - - color(new Color(81, 153, 226)); - footer("Developed by Tech & Team"); - } - - public TechEmbedBuilder(String title, boolean footer) { - if(title != null) - setAuthor(title, "https://techscode.com", "https://i.imgur.com/nnegGEV.png"); - if(footer) - footer("Developed by Tech & Team"); - - color(new Color(81, 153, 226)); - } - - public TechEmbedBuilder(boolean footer) { - if(footer) - footer("Developed by Tech & Team"); - - color(new Color(81, 153, 226)); - } - - public TechEmbedBuilder footer(String text) { - setFooter("Tech's Plugin Support • " + text, "https://i.imgur.com/nzfiUTy.png"); - - return this; - } - - public TechEmbedBuilder error() { - color(new Color(178,34,34)); - - return this; - } - - public TechEmbedBuilder success() { - color(new Color(50, 205, 50)); - - return this; - } - - public TechEmbedBuilder text(String text) { - setDescription(text); - - return this; - } - - public TechEmbedBuilder text(String... text) { - setDescription(String.join("\n", text)); - - return this; - } - - public TechEmbedBuilder thumbnail(String url) { - super.setThumbnail(url); - - return this; - } - - public TechEmbedBuilder color(Color color) { - if(color == null) - return this; - - super.setColor(color); - return this; - } - - public TechEmbedBuilder image(String url) { - super.setImage(url); - - return this; - } - - public TechEmbedBuilder field(String name, String value, boolean inline) { - super.addField(name, value, inline); - - return this; - } - - public TechEmbedBuilder blankField(boolean inline) { - super.addBlankField(inline); - - return this; - } - - public String getText() { - return super.getDescriptionBuilder().toString(); - } - - @Deprecated - // Try not to use this as it sleeps the bot basically. - public Message complete(TextChannel textChannel) { - return textChannel.sendMessage(build()).complete(); - } - - @Deprecated - // Try not to use this as it sleeps the bot basically. - public Message complete(Member member) { - return complete(member.getUser()); - } - - public Message complete(User user) { - try { - return user.openPrivateChannel().complete().sendMessage(build()).complete(); - } catch (ErrorResponseException ignore) { } - return null; - } - - public void queue(TextChannel textChannel) { - textChannel.sendMessageEmbeds(build()).queue(); - } - - public void queue(Member member) { - queue(member.getUser()); - } - - public void queue(Member member, Consumer<Message> consumer) { - queue(member.getUser(), consumer); - } - - public void queue(User user) { - try { - user.openPrivateChannel().submit() - .thenCompose(channel -> channel.sendMessageEmbeds(build()).submit()) - .whenComplete((message, error) -> { - if (error != null){ - TechDiscordBot.log("Could not send pm to "+user.getName()); - } - }); - } catch (Exception ignore) { } - } - - public void queue(User user, Consumer<Message> consumer) { - try { - user.openPrivateChannel().queue(c -> c.sendMessageEmbeds(build()).queue(consumer)); - } catch (Exception ignore) { } - } - - public void queue(TextChannel textChannel, Consumer<Message> consumer) { - textChannel.sendMessageEmbeds(build()).queue(consumer); - } - - public void queueAfter(TextChannel textChannel, int delay, TimeUnit unit) { - textChannel.sendMessageEmbeds(build()).queueAfter(delay, unit); - } - - public void queueAfter(TextChannel textChannel, int delay, TimeUnit unit, Consumer<Message> success) { - textChannel.sendMessageEmbeds(build()).queueAfter(delay, unit, success); - } - - public void queueAfter(User user, int delay, TimeUnit time) { - try { - user.openPrivateChannel().complete().sendMessageEmbeds(build()).queueAfter(delay, time); - } catch (ErrorResponseException ignore) { } - } - - public Message reply(Message message) { - return reply(message, true); - } - - public Message reply(Message message, boolean mention) { - return message.reply(build()).mentionRepliedUser(mention).complete(); - } - - public void replyTemporary(Message message, int duration, TimeUnit timeUnit) { - replyTemporary(message, true, duration, timeUnit); - } - - public void replyTemporary(Message message, boolean mention, int duration, TimeUnit timeUnit) { - message.replyEmbeds(build()).mentionRepliedUser(mention).queue((msg -> msg.delete().submitAfter(duration, timeUnit))); - } - - public void sendTemporary(TextChannel textChannel, int duration, TimeUnit timeUnit) { - queue(textChannel, (msg) -> msg.delete().submitAfter(duration, timeUnit)); - } - - public void sendTemporary(TextChannel textChannel, int duration) { - sendTemporary(textChannel, duration, TimeUnit.SECONDS); - } - - public ScheduledFuture<?> sendAfter(TextChannel textChannel, int duration, Consumer<Message> onSuccess) { - return textChannel.sendMessageEmbeds(build()).queueAfter(duration, TimeUnit.SECONDS, onSuccess); - } - - public ScheduledFuture<?> sendAfter(TextChannel textChannel, int duration, TimeUnit timeUnit, Consumer<Message> onSuccess) { - return textChannel.sendMessageEmbeds(build()).queueAfter(duration, timeUnit, onSuccess); - } -} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/utils/Changelog.java b/src/main/java/me/TechsCode/TechDiscordBot/utils/Changelog.java new file mode 100644 index 00000000..7c3049dc --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/utils/Changelog.java @@ -0,0 +1,62 @@ +package me.techscode.techdiscordbot.utils; + +public enum Changelog { + + V0_1_25( + "0.1.25", + "Added /update command", + "Added /manage command", + "Pre-release of the verification system" + ), + V0_2_0( + "0.2.0", + "Fixed RGB link in /answer hex", + "Removed apply command", + "Fixed /google command", + "Finished /ban", + "Cleanup in TicketStaff command", + "Removed unneeded method", + "Added more log messages to PayPal system", + "Added several new auto reply messages", + "Fixed text spacing in main file" + ); + + private final String version; + private final String[] changes; + + Changelog(String version, String... changes) { + this.version = version; + this.changes = changes; + } + + public String getVersion() { + return version; + } + + public String[] getChanges() { + return changes; + } + + public static Changelog getLatest() { + return values()[values().length - 1]; + } + + public static Changelog getByName(String name) { + for (Changelog changelog : values()) { + if (changelog.getVersion().equalsIgnoreCase(name)) { + return changelog; + } + } + return null; + } + + public static Changelog getByVersion(String version) { + for (Changelog changelog : values()) { + if (changelog.getVersion().equalsIgnoreCase(version)) { + return changelog; + } + } + return null; + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/utils/HumanTime.java b/src/main/java/me/TechsCode/TechDiscordBot/utils/HumanTime.java new file mode 100644 index 00000000..98d332f2 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/utils/HumanTime.java @@ -0,0 +1,788 @@ +/* + * HumanTime.java + * + * Created on 06.10.2008 + * + * Copyright (c) 2008 Johann Burkard (<mailto:jb@eaio.com>) <http://eaio.com> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ +package com.eaio.util.text; + +import java.io.Externalizable; +import java.io.IOException; +import java.io.ObjectInput; +import java.io.ObjectOutput; +import java.util.Iterator; + +/** + * HumanTime parses and formats time deltas for easier reading by humans. It can format time information without losing + * information but its main purpose is to generate more easily understood approximations. + * <h3>Using HumanTime</h3> + * <p> + * Use HumanTime by creating an instance that contains the time delta ({@link HumanTime#HumanTime(long)}), create an + * empty instance through ({@link HumanTime#HumanTime()}) and set the delta using the {@link #y()}, {@link #d()}, + * {@link #h()}, {@link #s()} and {@link #ms()} methods or parse a {@link CharSequence} representation ({@link #eval(CharSequence)}). + * Parsing ignores whitespace and is case insensitive. + * </p> + * <h3>HumanTime format</h3> + * <p> + * HumanTime will format time deltas in years ("y"), days ("d"), hours ("h"), minutes ("m"), seconds ("s") and + * milliseconds ("ms"), separated by a blank character. For approximate representations, the time delta will be round up + * or down if necessary. + * </p> + * <h3>HumanTime examples</h3> + * <ul> + * <li>HumanTime.eval("1 d 1d 2m 3m").getExactly() = "2 d 5 m"</li> + * <li>HumanTime.eval("2m8d2h4m").getExactly() = "8 d 2 h 6 m"</li> + * <li>HumanTime.approximately("2 d 8 h 20 m 50 s") = "2 d 8 h"</li> + * <li>HumanTime.approximately("55m") = "1 h"</li> + * </ul> + * <h3>Implementation details</h3> + * <ul> + * <li>The time delta can only be increased.</li> + * <li>Instances of this class are thread safe.</li> + * <li>Getters using the Java Beans naming conventions are provided for use in environments like JSP or with expression + * languages like OGNL. See {@link #getApproximately()} and {@link #getExactly()}.</li> + * <li>To keep things simple, a year consists of 365 days.</li> + * </ul> + * + * @author <a href="mailto:jb@eaio.com">Johann Burkard</a> + * @version $Id: HumanTime.java 3906 2011-05-21 13:56:05Z johann $ + * @see #eval(CharSequence) + * @see #approximately(CharSequence) + * @see <a href="http://johannburkard.de/blog/programming/java/date-formatting-parsing-humans-humantime.html">Date Formatting and Parsing for Humans in Java with HumanTime</a> + */ +public class HumanTime implements Externalizable, Comparable<HumanTime>, Cloneable { + + /** + * The serial version UID. + */ + private static final long serialVersionUID = 5179328390732826722L; + + /** + * One second. + */ + private static final long SECOND = 1000; + + /** + * One minute. + */ + private static final long MINUTE = SECOND * 60; + + /** + * One hour. + */ + private static final long HOUR = MINUTE * 60; + + /** + * One day. + */ + private static final long DAY = HOUR * 24; + + /** + * One year. + */ + private static final long YEAR = DAY * 365; + + /** + * Percentage of what is round up or down. + */ + private static final int CEILING_PERCENTAGE = 15; + + /** + * Parsing state. + */ + static enum State { + + NUMBER, IGNORED, UNIT + + } + + static State getState(char c) { + State out; + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + out = State.NUMBER; + break; + case 's': + case 'm': + case 'h': + case 'd': + case 'y': + case 'S': + case 'M': + case 'H': + case 'D': + case 'Y': + out = State.UNIT; + break; + default: + out = State.IGNORED; + } + return out; + } + + /** + * Parses a {@link CharSequence} argument and returns a {@link HumanTime} instance. + * + * @param s the char sequence, may not be <code>null</code> + * @return an instance, never <code>null</code> + */ + public static HumanTime eval(final CharSequence s) { + HumanTime out = new HumanTime(0L); + + int num = 0; + + int start = 0; + int end = 0; + + State oldState = State.IGNORED; + + for (char c : new Iterable<Character>() { + + /** + * @see java.lang.Iterable#iterator() + */ + public Iterator<Character> iterator() { + return new Iterator<Character>() { + + private int p = 0; + + /** + * @see java.util.Iterator#hasNext() + */ + public boolean hasNext() { + return p < s.length(); + } + + /** + * @see java.util.Iterator#next() + */ + public Character next() { + return s.charAt(p++); + } + + /** + * @see java.util.Iterator#remove() + */ + public void remove() { + throw new UnsupportedOperationException(); + } + + }; + } + + }) { + State newState = getState(c); + if (oldState != newState) { + if (oldState == State.NUMBER && (newState == State.IGNORED || newState == State.UNIT)) { + num = Integer.parseInt(s.subSequence(start, end).toString()); + } + else if (oldState == State.UNIT && (newState == State.IGNORED || newState == State.NUMBER)) { + out.nTimes(s.subSequence(start, end).toString(), num); + num = 0; + } + start = end; + } + ++end; + oldState = newState; + } + if (oldState == State.UNIT) { + out.nTimes(s.subSequence(start, end).toString(), num); + } + + return out; + } + + /** + * Parses and formats the given char sequence, preserving all data. + * <p> + * Equivalent to <code>eval(in).getExactly()</code> + * + * @param in the char sequence, may not be <code>null</code> + * @return a formatted String, never <code>null</code> + */ + public static String exactly(CharSequence in) { + return eval(in).getExactly(); + } + + /** + * Formats the given time delta, preserving all data. + * <p> + * Equivalent to <code>new HumanTime(in).getExactly()</code> + * + * @param l the time delta + * @return a formatted String, never <code>null</code> + */ + public static String exactly(long l) { + return new HumanTime(l).getExactly(); + } + + /** + * Parses and formats the given char sequence, potentially removing some data to make the output easier to + * understand. + * <p> + * Equivalent to <code>eval(in).getApproximately()</code> + * + * @param in the char sequence, may not be <code>null</code> + * @return a formatted String, never <code>null</code> + */ + public static String approximately(CharSequence in) { + return eval(in).getApproximately(); + } + + /** + * Formats the given time delta, preserving all data. + * <p> + * Equivalent to <code>new HumanTime(l).getApproximately()</code> + * + * @param l the time delta + * @return a formatted String, never <code>null</code> + */ + public static String approximately(long l) { + return new HumanTime(l).getApproximately(); + } + + /** + * The time delta. + */ + private long delta; + + /** + * No-argument Constructor for HumanTime. + * <p> + * Equivalent to calling <code>new HumanTime(0L)</code>. + */ + public HumanTime() { + this(0L); + } + + /** + * Constructor for HumanTime. + * + * @param delta the initial time delta, interpreted as a positive number + */ + public HumanTime(long delta) { + super(); + this.delta = Math.abs(delta); + } + + private void nTimes(String unit, int n) { + if ("ms".equalsIgnoreCase(unit)) { + ms(n); + } + else if ("s".equalsIgnoreCase(unit)) { + s(n); + } + else if ("m".equalsIgnoreCase(unit)) { + m(n); + } + else if ("h".equalsIgnoreCase(unit)) { + h(n); + } + else if ("d".equalsIgnoreCase(unit)) { + d(n); + } + else if ("y".equalsIgnoreCase(unit)) { + y(n); + } + } + + private long upperCeiling(long x) { + return (x / 100) * (100 - CEILING_PERCENTAGE); + } + + private long lowerCeiling(long x) { + return (x / 100) * CEILING_PERCENTAGE; + } + + private String ceil(long d, long n) { + return Integer.toString((int) Math.ceil((double) d / n)); + } + + private String floor(long d, long n) { + return Integer.toString((int) Math.floor((double) d / n)); + } + + /** + * Adds one year to the time delta. + * + * @return this HumanTime object + */ + public HumanTime y() { + return y(1); + } + + /** + * Adds n years to the time delta. + * + * @param n n + * @return this HumanTime object + */ + public HumanTime y(int n) { + delta += YEAR * Math.abs(n); + return this; + } + + /** + * Adds one day to the time delta. + * + * @return this HumanTime object + */ + public HumanTime d() { + return d(1); + } + + /** + * Adds n days to the time delta. + * + * @param n n + * @return this HumanTime object + */ + public HumanTime d(int n) { + delta += DAY * Math.abs(n); + return this; + } + + /** + * Adds one hour to the time delta. + * + * @return this HumanTime object + */ + public HumanTime h() { + return h(1); + } + + /** + * Adds n hours to the time delta. + * + * @param n n + * @return this HumanTime object + */ + public HumanTime h(int n) { + delta += HOUR * Math.abs(n); + return this; + } + + /** + * Adds one month to the time delta. + * + * @return this HumanTime object + */ + public HumanTime m() { + return m(1); + } + + /** + * Adds n months to the time delta. + * + * @param n n + * @return this HumanTime object + */ + public HumanTime m(int n) { + delta += MINUTE * Math.abs(n); + return this; + } + + /** + * Adds one second to the time delta. + * + * @return this HumanTime object + */ + public HumanTime s() { + return s(1); + } + + /** + * Adds n seconds to the time delta. + * + * @param n seconds + * @return this HumanTime object + */ + public HumanTime s(int n) { + delta += SECOND * Math.abs(n); + return this; + } + + /** + * Adds one millisecond to the time delta. + * + * @return this HumanTime object + */ + public HumanTime ms() { + return ms(1); + } + + /** + * Adds n milliseconds to the time delta. + * + * @param n n + * @return this HumanTime object + */ + public HumanTime ms(int n) { + delta += Math.abs(n); + return this; + } + + /** + * Returns a human-formatted representation of the time delta. + * + * @return a formatted representation of the time delta, never <code>null</code> + */ + public String getExactly() { + return getExactly(new StringBuilder()).toString(); + } + + /** + * Appends a human-formatted representation of the time delta to the given {@link Appendable} object. + * + * @param <T> the return type + * @param a the Appendable object, may not be <code>null</code> + * @return the given Appendable object, never <code>null</code> + */ + public <T extends Appendable> T getExactly(T a) { + try { + boolean prependBlank = false; + long d = delta; + if (d >= YEAR) { + a.append(floor(d, YEAR)); + a.append(' '); + a.append('y'); + prependBlank = true; + } + d %= YEAR; + if (d >= DAY) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, DAY)); + a.append(' '); + a.append('d'); + prependBlank = true; + } + d %= DAY; + if (d >= HOUR) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, HOUR)); + a.append(' '); + a.append('h'); + prependBlank = true; + } + d %= HOUR; + if (d >= MINUTE) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, MINUTE)); + a.append(' '); + a.append('m'); + prependBlank = true; + } + d %= MINUTE; + if (d >= SECOND) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, SECOND)); + a.append(' '); + a.append('s'); + prependBlank = true; + } + d %= SECOND; + if (d > 0) { + if (prependBlank) { + a.append(' '); + } + a.append(Integer.toString((int) d)); + a.append(' '); + a.append('m'); + a.append('s'); + } + } + catch (IOException ex) { + // What were they thinking... + } + return a; + } + + /** + * Returns an approximate, human-formatted representation of the time delta. + * + * @return a formatted representation of the time delta, never <code>null</code> + */ + public String getApproximately() { + return getApproximately(new StringBuilder()).toString(); + } + + /** + * Appends an approximate, human-formatted representation of the time delta to the given {@link Appendable} object. + * + * @param <T> the return type + * @param a the Appendable object, may not be <code>null</code> + * @return the given Appendable object, never <code>null</code> + */ + public <T extends Appendable> T getApproximately(T a) { + + try { + int parts = 0; + boolean rounded = false; + boolean prependBlank = false; + long d = delta; + long mod = d % YEAR; + + if (mod >= upperCeiling(YEAR)) { + a.append(ceil(d, YEAR)); + a.append(' '); + a.append('y'); + ++parts; + rounded = true; + prependBlank = true; + } + else if (d >= YEAR) { + a.append(floor(d, YEAR)); + a.append(' '); + a.append('y'); + ++parts; + rounded = mod <= lowerCeiling(YEAR); + prependBlank = true; + } + + if (!rounded) { + d %= YEAR; + mod = d % DAY; + + if (mod >= upperCeiling(DAY)) { + if (prependBlank) { + a.append(' '); + } + a.append(ceil(d, DAY)); + a.append(' '); + a.append('d'); + ++parts; + rounded = true; + prependBlank = true; + } + else if (d >= DAY) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, DAY)); + a.append(' '); + a.append('d'); + ++parts; + rounded = mod <= lowerCeiling(DAY); + prependBlank = true; + } + + if (parts < 2) { + d %= DAY; + mod = d % HOUR; + + if (mod >= upperCeiling(HOUR)) { + if (prependBlank) { + a.append(' '); + } + a.append(ceil(d, HOUR)); + a.append(' '); + a.append('h'); + ++parts; + rounded = true; + prependBlank = true; + } + else if (d >= HOUR && !rounded) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, HOUR)); + a.append(' '); + a.append('h'); + ++parts; + rounded = mod <= lowerCeiling(HOUR); + prependBlank = true; + } + + if (parts < 2) { + d %= HOUR; + mod = d % MINUTE; + + if (mod >= upperCeiling(MINUTE)) { + if (prependBlank) { + a.append(' '); + } + a.append(ceil(d, MINUTE)); + a.append(' '); + a.append('m'); + ++parts; + rounded = true; + prependBlank = true; + } + else if (d >= MINUTE && !rounded) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, MINUTE)); + a.append(' '); + a.append('m'); + ++parts; + rounded = mod <= lowerCeiling(MINUTE); + prependBlank = true; + } + + if (parts < 2) { + d %= MINUTE; + mod = d % SECOND; + + if (mod >= upperCeiling(SECOND)) { + if (prependBlank) { + a.append(' '); + } + a.append(ceil(d, SECOND)); + a.append(' '); + a.append('s'); + ++parts; + rounded = true; + prependBlank = true; + } + else if (d >= SECOND && !rounded) { + if (prependBlank) { + a.append(' '); + } + a.append(floor(d, SECOND)); + a.append(' '); + a.append('s'); + ++parts; + rounded = mod <= lowerCeiling(SECOND); + prependBlank = true; + } + + if (parts < 2) { + d %= SECOND; + + if (d > 0 && !rounded) { + if (prependBlank) { + a.append(' '); + } + a.append(Integer.toString((int) d)); + a.append(' '); + a.append('m'); + a.append('s'); + } + } + + } + + } + + } + } + } + catch (IOException ex) { + // What were they thinking... + } + + return a; + } + + /** + * Returns the time delta. + * + * @return the time delta + */ + public long getDelta() { + return delta; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof HumanTime)) { + return false; + } + return delta == ((HumanTime) obj).delta; + } + + /** + * Returns a 32-bit representation of the time delta. + * + * @see java.lang.Object#hashCode() + */ + public int hashCode() { + return (int) (delta ^ (delta >> 32)); + } + + /** + * Returns a String representation of this. + * <p> + * The output is identical to {@link #getExactly()}. + * + * @see java.lang.Object#toString() + * @see #getExactly() + * @return a String, never <code>null</code> + */ + public String toString() { + return getExactly(); + } + + /** + * Compares this HumanTime to another HumanTime. + * + * @param t the other instance, may not be <code>null</code> + * @return which one is greater + */ + public int compareTo(HumanTime t) { + return delta == t.delta ? 0 : (delta < t.delta ? -1 : 1); + } + + /** + * Deep-clones this object. + * + * @see java.lang.Object#clone() + * @throws CloneNotSupportedException + */ + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + /** + * @see java.io.Externalizable#readExternal(java.io.ObjectInput) + */ + public void readExternal(ObjectInput in) throws IOException { + delta = in.readLong(); + } + + /** + * @see java.io.Externalizable#writeExternal(java.io.ObjectOutput) + */ + public void writeExternal(ObjectOutput out) throws IOException { + out.writeLong(delta); + } + +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/utils/JsonReader.java b/src/main/java/me/TechsCode/TechDiscordBot/utils/JsonReader.java new file mode 100644 index 00000000..4452091e --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/utils/JsonReader.java @@ -0,0 +1,118 @@ +package me.techscode.techdiscordbot.utils; + +import org.jetbrains.annotations.NotNull; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; + +public class JsonReader { + + /** + * An util that allows you to read JSON Objects + * + * @param rd The reader + * @return String + * @throws IOException Possible IOException + */ + private static @NotNull String readAll(@NotNull final Reader rd) throws IOException { + final StringBuilder sb = new StringBuilder(); + int cp; + while ((cp = rd.read()) != -1) { + sb.append((char) cp); + } + return sb.toString(); + } + + /** + * An util that allows you to read JSON Objects + * + * @param url The URL + * @return JSONObject + * @throws IOException Possible IOException + * @throws JSONException Possible JSONException + */ + public static @NotNull JSONArray readJsonFromUrl(final String url) throws IOException, JSONException { + try (InputStream inputStream = new URL(url).openStream()) { + final BufferedReader rd = new BufferedReader( + new InputStreamReader( + inputStream, StandardCharsets.UTF_8 + ) + ); + + final String jsonText = readAll(rd); + return new JSONArray(jsonText); + } + } + + public static JSONObject makePostRequest(final String url) throws Exception { + final URL obj = new URL(url); + final HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // Set request method to POST + con.setRequestMethod("POST"); + + // Add request header + con.setRequestProperty("Content-Type", "application/json"); + + // Send post request + con.setDoOutput(true); + final DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.flush(); + wr.close(); + + final int responseCode = con.getResponseCode(); + System.out.println("Response Code: " + responseCode); + + final BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + final StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + return new JSONObject(response.toString()); + } + + public static JSONObject makePolymartPostRequest(final String url, final String apiKey) throws Exception { + final URL obj = new URL(url); + final HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // Set request method to POST + con.setRequestMethod("POST"); + + // Add request header + con.setRequestProperty("Content-Type", "application/json"); + + // Send post request + con.setDoOutput(true); + final DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + + // Add API key to request body as JSON data + final JSONObject postData = new JSONObject(); + postData.put("api_key", apiKey); + wr.writeBytes(postData.toString()); + wr.flush(); + wr.close(); + + final int responseCode = con.getResponseCode(); + System.out.println("Response Code: " + responseCode); + + final BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + final StringBuilder response = new StringBuilder(); + + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + + return new JSONObject(response.toString()); + } +} diff --git a/src/main/java/me/TechsCode/TechDiscordBot/utils/ProjectUtil.java b/src/main/java/me/TechsCode/TechDiscordBot/utils/ProjectUtil.java new file mode 100644 index 00000000..8e26a452 --- /dev/null +++ b/src/main/java/me/TechsCode/TechDiscordBot/utils/ProjectUtil.java @@ -0,0 +1,143 @@ +package me.techscode.techdiscordbot.utils; + +import com.greazi.discordbotfoundation.Common; +import com.greazi.discordbotfoundation.debug.Debugger; +import net.sourceforge.tess4j.ITesseract; +import net.sourceforge.tess4j.Tesseract; +import net.sourceforge.tess4j.TesseractException; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.imageio.ImageIO; +import javax.swing.*; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageFilter; +import java.awt.image.ImageProducer; +import java.io.*; +import java.net.URL; +import java.security.CodeSource; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Objects; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class ProjectUtil { + + @NotNull + public static String[] getFiles() { + ArrayList<String> names = new ArrayList<>(); + try { + CodeSource src = ProjectUtil.class.getProtectionDomain().getCodeSource(); + if (src != null) { + URL jar = src.getLocation(); + ZipInputStream zip = new ZipInputStream(jar.openStream()); + while(true) { + ZipEntry e = zip.getNextEntry(); + if (e == null) break; + names.add(e.getName()); + } + } + } catch (IOException e) { + Common.throwError(e, "Failed to get files"); + } + return names.toArray(new String[0]); + } + + @NotNull + public static Class<?>[] getClasses(String prefix) { + return Arrays.stream(getFiles()) + .filter(fileName -> fileName.endsWith(".class")) + .map(className -> className.replace("/", ".").replace(".class", "")) + .filter(fileName -> fileName.startsWith(prefix)) + .map(className -> { + try { + return Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + return null; + } + }) + .filter(Objects::nonNull) + .toArray(Class[]::new); + } + + @NotNull + @Contract(pure = true) + public static String removeFront(@NotNull String s, int am) { + return s.substring(am); + } + + @NotNull + public static String removeEnd(@NotNull String s, int am) { + return s.substring(0, s.length() - am); + } + + @NotNull + public static String removeBoth(@NotNull String s, int am) { + return s.substring(am, s.length() - am); + } + + @Nullable + public static String getTextFromImage(File imageFile) { + ITesseract tesseract = new Tesseract(); + try { + tesseract.setLanguage("eng"); + String temp = tesseract.doOCR(imageFile); + return temp; + } catch (TesseractException e) { + Common.throwError(e, "Failed to read image"); + return null; + } + } + + @Nullable + public static File GrayScale(InputStream inputStream) { + + try { + + // TODO: + // Saves tempFile is 0KB meaning there is no image. + // This might be an issue with inputStream.read(buffer); + byte[] buffer = new byte[inputStream.available()]; + inputStream.read(buffer); + File tempFile = File.createTempFile("tempImage", ".png"); + OutputStream outStream = new FileOutputStream(tempFile); + outStream.write(buffer); + + Debugger.debug("Image2", "Image saved to " + tempFile.getAbsolutePath()); + + BufferedImage image = ImageIO.read(tempFile); + int width = image.getWidth(); + int height = image.getHeight(); + + for(int i=0; i<height; i++) { + + for(int j=0; j<width; j++) { + + Color c = new Color(image.getRGB(j, i)); + int red = (int)(c.getRed() * 0.299); + int green = (int)(c.getGreen() * 0.587); + int blue = (int)(c.getBlue() *0.114); + Color newColor = new Color(red+green+blue, + + red+green+blue,red+green+blue); + + image.setRGB(j,i,newColor.getRGB()); + } + } + + File ouptut = new File("grayscale.jpg"); + ImageIO.write(image, "jpg", ouptut); + + return ouptut; + + } catch (Exception e) { + Common.throwError(e, "Failed to grayscale image"); + } + return null; + } +} \ No newline at end of file