From a58b73ba32886656bb47565e69ff813d648ec66e Mon Sep 17 00:00:00 2001 From: Mathias Wagner <germannewsmaker@gmail.com> Date: Tue, 6 Sep 2022 16:18:49 +0200 Subject: [PATCH] Added the Sheepstar Core V1 --- SheepstarCoreV1/.github/workflows/ci.yml | 17 + SheepstarCoreV1/.github/workflows/release.yml | 42 ++ SheepstarCoreV1/.gitignore | 5 + SheepstarCoreV1/README.md | 98 ++++ SheepstarCoreV1/pom.xml | 177 +++++++ .../xyz/sheepstar/core/SheepstarCore.java | 78 +++ .../commands/console/GetSettingCommand.java | 37 ++ .../console/GetSettingInfoCommand.java | 35 ++ .../core/commands/console/HelpCommand.java | 28 + .../console/InsertSettingInfoCommand.java | 33 ++ .../commands/console/LoadModuleCommand.java | 25 + .../core/commands/console/QueryCommand.java | 43 ++ .../commands/console/ShutdownCommand.java | 28 + .../commands/console/TranslationCommand.java | 35 ++ .../console/UpdateSettingCommand.java | 39 ++ .../core/commands/general/BuyCommand.java | 47 ++ .../general/DisableModuleCommand.java | 20 + .../commands/general/EnableModuleCommand.java | 33 ++ .../core/commands/general/HelpCommand.java | 21 + .../core/commands/general/InfoCommand.java | 20 + .../commands/general/ListCommandsCommand.java | 60 +++ .../commands/general/ListSettingsCommand.java | 35 ++ .../core/commands/general/PingCommand.java | 21 + .../core/commands/general/RedeemCommand.java | 36 ++ .../commands/general/SetSettingCommand.java | 37 ++ .../core/commands/general/ShopCommand.java | 67 +++ .../commands/general/ShowCoinsCommand.java | 23 + .../commands/general/ShowPrefixCommand.java | 33 ++ .../general/SwitchLanguageCommand.java | 57 ++ .../java/xyz/sheepstar/util/Sheepstar.java | 62 +++ .../xyz/sheepstar/util/SheepstarImpl.java | 488 ++++++++++++++++++ .../sheepstar/util/action/RepeatedAction.java | 31 ++ .../util/action/ScheduledExecutorPool.java | 60 +++ .../message/BeautifulDescriptionBuilder.java | 68 +++ .../builder/message/DefaultEmbedBuilder.java | 261 ++++++++++ .../message/DefaultResponseBuilder.java | 334 ++++++++++++ .../util/bot/builder/message/FieldEmote.java | 30 ++ .../bot/builder/message/MessageField.java | 87 ++++ .../util/bot/builder/message/MessageType.java | 34 ++ .../util/bot/builder/message/Translate.java | 25 + .../sheepstar/util/bot/command/Arguments.java | 116 +++++ .../util/bot/command/CommandRunnable.java | 7 + .../util/bot/command/GuildCommand.java | 367 +++++++++++++ .../bot/command/GuildEventController.java | 395 ++++++++++++++ .../bot/command/PublicCommandException.java | 37 ++ .../util/bot/command/SyntaxBuilder.java | 32 ++ .../bot/command/annotations/CommandMeta.java | 23 + .../command/general/GeneralGuildCommand.java | 92 ++++ .../util/bot/emote/INTERN_EMOTE.java | 35 ++ .../util/bot/listener/GuildListener.java | 24 + .../util/bot/listener/ListenerBasics.java | 298 +++++++++++ .../util/bot/listener/ListenerInfo.java | 47 ++ .../util/bot/manager/BotManager.java | 111 ++++ .../util/bot/manager/ImportManager.java | 60 +++ .../bot/manager/sql/CommandMetaManager.java | 68 +++ .../util/bot/manager/sql/GuildManager.java | 121 +++++ .../util/bot/manager/sql/LanguageManager.java | 84 +++ .../util/bot/manager/sql/ModuleManager.java | 136 +++++ .../bot/manager/sql/SettingsInfoManager.java | 140 +++++ .../util/bot/manager/sql/SettingsManager.java | 107 ++++ .../bot/manager/sql/TranslationManager.java | 100 ++++ .../util/bot/permission/PermissionNode.java | 11 + .../util/bot/updater/StatusUpdater.java | 107 ++++ .../configuration/CommandConfiguration.java | 64 +++ .../configuration/DatabaseConfiguration.java | 60 +++ .../PermissionConfiguration.java | 37 ++ .../configuration/SheepstarConfiguration.java | 128 +++++ .../SupporterPermissionConfiguration.java | 36 ++ .../entity/SheepstarActivity.java | 38 ++ .../configuration/entity/SheepstarPool.java | 36 ++ .../util/console/ConsoleCommand.java | 83 +++ .../util/console/ConsoleCommandField.java | 76 +++ .../util/console/ConsoleListenerThread.java | 33 ++ .../util/console/ConsoleManager.java | 96 ++++ .../ConsoleMessageReceivedListener.java | 19 + .../sheepstar/util/event/SheepstarEvent.java | 43 ++ .../sheepstar/util/event/api/EventData.java | 21 + .../util/event/api/EventListener.java | 11 + .../util/event/api/EventManager.java | 93 ++++ .../sheepstar/util/event/api/Listener.java | 4 + .../util/event/console/ConsoleEvent.java | 17 + .../console/ConsoleMessageReceivedEvent.java | 29 ++ .../util/event/module/ModuleEvent.java | 30 ++ .../util/event/module/ModuleLoadedEvent.java | 18 + .../util/event/module/ModuleLoadingEvent.java | 17 + .../sheepstar/util/http/client/Endpoint.java | 100 ++++ .../util/http/client/ErrorResponse.java | 26 + .../sheepstar/util/http/client/Request.java | 77 +++ .../util/http/client/RequestMethod.java | 11 + .../sheepstar/util/http/client/Requester.java | 77 +++ .../sheepstar/util/http/client/Response.java | 70 +++ .../util/http/client/RestAction.java | 12 + .../xyz/sheepstar/util/http/client/Route.java | 94 ++++ .../internal/article/FindArticleInfoImpl.java | 40 ++ .../article/GetArticleInfoActionImpl.java | 37 ++ .../article/GetArticlesActionImpl.java | 48 ++ .../internal/gift/GiftInfoActionImpl.java | 44 ++ .../internal/gift/RedeemGiftActionImpl.java | 42 ++ .../shop/ActivateArticleActionImpl.java | 40 ++ .../internal/shop/HasArticleActionImpl.java | 39 ++ .../internal/shop/ShopItemsActionImpl.java | 70 +++ .../util/http/client/entities/Article.java | 70 +++ .../util/http/client/entities/Gift.java | 35 ++ .../util/http/client/entities/ShopItem.java | 36 ++ .../client/entities/internal/ArticleImpl.java | 106 ++++ .../client/entities/internal/GiftImpl.java | 53 ++ .../entities/internal/ShopItemImpl.java | 63 +++ .../http/client/internal/RestActionImpl.java | 69 +++ .../http/client/objects/ArticleObject.java | 28 + .../util/http/client/objects/GiftObject.java | 26 + .../util/http/client/objects/ShopObject.java | 54 ++ .../objects/internal/ArticleObjectImpl.java | 41 ++ .../objects/internal/GiftObjectImpl.java | 34 ++ .../objects/internal/ShopObjectImpl.java | 51 ++ .../sheepstar/util/http/server/WebServer.java | 22 + .../util/internal/manager/CacheManager.java | 74 +++ .../manager/ConfigurationManager.java | 90 ++++ .../internal/manager/ListenerManager.java | 235 +++++++++ .../util/internal/manager/OptionManager.java | 99 ++++ .../xyz/sheepstar/util/log/LogManager.java | 18 + .../sheepstar/util/mapper/JSONContent.java | 199 +++++++ .../util/mapper/SheepstarMapper.java | 36 ++ .../util/module/ActivatedModule.java | 59 +++ .../xyz/sheepstar/util/module/Module.java | 62 +++ .../sheepstar/util/module/ModuleManager.java | 267 ++++++++++ .../util/module/SheepstarModule.java | 99 ++++ .../util/sql/DatabaseCheckerThread.java | 39 ++ .../xyz/sheepstar/util/sql/SheepDatabase.java | 48 ++ .../xyz/sheepstar/util/sql/SheepManager.java | 65 +++ .../util/sql/SimpleDeletionProcess.java | 63 +++ .../xyz/sheepstar/util/sql/StorageMedium.java | 80 +++ .../validation/trigger/TriggerValidation.java | 13 + .../validation/trigger/TriggerValidator.java | 53 ++ .../src/main/resources/log4j.properties | 18 + 134 files changed, 9349 insertions(+) create mode 100644 SheepstarCoreV1/.github/workflows/ci.yml create mode 100644 SheepstarCoreV1/.github/workflows/release.yml create mode 100644 SheepstarCoreV1/.gitignore create mode 100644 SheepstarCoreV1/README.md create mode 100644 SheepstarCoreV1/pom.xml create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/SheepstarCore.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingInfoCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/HelpCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/InsertSettingInfoCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/LoadModuleCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/QueryCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/ShutdownCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/TranslationCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/UpdateSettingCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/BuyCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/DisableModuleCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/EnableModuleCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/HelpCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/InfoCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListCommandsCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListSettingsCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/PingCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/RedeemCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SetSettingCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShopCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowCoinsCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowPrefixCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SwitchLanguageCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/Sheepstar.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/SheepstarImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/RepeatedAction.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/ScheduledExecutorPool.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/BeautifulDescriptionBuilder.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultEmbedBuilder.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultResponseBuilder.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/FieldEmote.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageField.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageType.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/Translate.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/Arguments.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/CommandRunnable.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildEventController.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/PublicCommandException.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/SyntaxBuilder.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/annotations/CommandMeta.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/general/GeneralGuildCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/emote/INTERN_EMOTE.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/GuildListener.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerBasics.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerInfo.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/BotManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/ImportManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/CommandMetaManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/GuildManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/LanguageManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/ModuleManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsInfoManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/TranslationManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/permission/PermissionNode.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/updater/StatusUpdater.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/CommandConfiguration.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/DatabaseConfiguration.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/PermissionConfiguration.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SheepstarConfiguration.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SupporterPermissionConfiguration.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarActivity.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarPool.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommand.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommandField.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleListenerThread.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleMessageReceivedListener.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/SheepstarEvent.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventData.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventListener.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/Listener.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleEvent.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleMessageReceivedEvent.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleEvent.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadedEvent.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadingEvent.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Endpoint.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/ErrorResponse.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Request.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RequestMethod.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Requester.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Response.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RestAction.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Route.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/FindArticleInfoImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticleInfoActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticlesActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/GiftInfoActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/RedeemGiftActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ActivateArticleActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/HasArticleActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ShopItemsActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Article.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Gift.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/ShopItem.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ArticleImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/GiftImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ShopItemImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/internal/RestActionImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ArticleObject.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/GiftObject.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ShopObject.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ArticleObjectImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/GiftObjectImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ShopObjectImpl.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/server/WebServer.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/CacheManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ConfigurationManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ListenerManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/OptionManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/log/LogManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/JSONContent.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/SheepstarMapper.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ActivatedModule.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/Module.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ModuleManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/SheepstarModule.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/DatabaseCheckerThread.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepDatabase.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepManager.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SimpleDeletionProcess.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/StorageMedium.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidation.java create mode 100644 SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidator.java create mode 100644 SheepstarCoreV1/src/main/resources/log4j.properties diff --git a/SheepstarCoreV1/.github/workflows/ci.yml b/SheepstarCoreV1/.github/workflows/ci.yml new file mode 100644 index 0000000..c3382f2 --- /dev/null +++ b/SheepstarCoreV1/.github/workflows/ci.yml @@ -0,0 +1,17 @@ +name: Java CI + +on: [push] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK + uses: actions/setup-java@v2 + with: + java-version: '8' + distribution: 'adopt' + - name: Build with Maven + run: mvn --batch-mode --update-snapshots verify \ No newline at end of file diff --git a/SheepstarCoreV1/.github/workflows/release.yml b/SheepstarCoreV1/.github/workflows/release.yml new file mode 100644 index 0000000..89f13c8 --- /dev/null +++ b/SheepstarCoreV1/.github/workflows/release.yml @@ -0,0 +1,42 @@ +name: Upload the latest sheepstar release + +on: + push: + branches: [ master ] + +jobs: + create: + name: "Creates the newest sheepstar release" + runs-on: "ubuntu-latest" + + steps: + - name: Checkout + uses: actions/checkout@v2.3.4 + + - name: Setup java + uses: actions/setup-java@v2 + with: + distribution: 'temurin' + java-version: '8' + + - name: Build + run: "mvn compile assembly:single" + + - name: Create Javadoc + run: | + mvn javadoc:javadoc + zip -r docs.zip ./target/site + + - name: Get version + id: get_version + run: echo "::set-output name=version::$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' exec:exec)" + + - uses: "marvinpinto/action-automatic-releases@latest" + with: + repo_token: "${{ secrets.GITHUB_TOKEN }}" + automatic_release_tag: ${{ steps.get_version.outputs.version }} + prerelease: false + title: Release ${{ steps.get_version.outputs.version }} + files: | + ./target/*.jar + ./docs.zip \ No newline at end of file diff --git a/SheepstarCoreV1/.gitignore b/SheepstarCoreV1/.gitignore new file mode 100644 index 0000000..6b516f4 --- /dev/null +++ b/SheepstarCoreV1/.gitignore @@ -0,0 +1,5 @@ +# Project exclude paths +/target/ +/env +/.idea/ +/SheepstarCore.iml diff --git a/SheepstarCoreV1/README.md b/SheepstarCoreV1/README.md new file mode 100644 index 0000000..bf3b979 --- /dev/null +++ b/SheepstarCoreV1/README.md @@ -0,0 +1,98 @@ +<h1 align="center">Sheepstar Core</h1> + +## About The Project + +This is the official Sheepstar Core. It was written with java and made to run with the JDA. Have fun during programming +your own modules :p + +## Getting Started + +### Installation + +1. Create a new project in your IDE +2. Import the dependency from https://jitpack.io/#sheepstar-dc/SheepstarCore +3. Create an `.env` folder (or another folder in which you want to load the runtime) +4. Create a `config.json` file in your `.env` folder and replace it to your needs + ```json + { + "token": "the discord bot token", + "api_key": "the key of the sheepstar api", + "api_url": "https://api.sheepstar.xyz", + "moduleDirectory": "modules", + "mysql": { + "hostname": "localhost", + "username": "username", + "password": "password", + "database": "database" + }, + "commands": { + "enable_ping_feature": true, + "enable_prefix_feature": true, + "enable_slash_feature": true, + "debug_guild": "guildID / leave empty to set global" + }, + "permissions": { + "BOT_OWNER": [ + "357214370188492802", + "386242172632170496" + ], + "SUPPORTER": { + "guildID": "846497208086167602", + "roleID": "860823465329295380" + } + }, + "activities": [ + { + "type": "WATCHING", + "name": "discord.gg/dAe7BPsHZc" + }, + { + "type": "LISTENING", + "name": "/help" + }, + { + "type": "WATCHING", + "name": "sheepstar.xyz" + } + ], + "pools": [ + { + "name": "SR-PreparePool", + "cores": 16 + }, + { + "name": "SR-CommandPool", + "cores": 8 + }, + { + "name": "SR-ListenerPool", + "cores": 8 + }, + { + "name": "SR-ActionPool", + "cores": 4 + } + ] + } + ``` +5. Add a `module.yml` file into your resources + ```yaml + main: xyz.sheepstar.exampleModule.Bootstrap # your main class + name: example module # your module name + author: Mathias Wagner # the name of the author + ``` + +### Optional: Instant reloading (Only works in IntelliJ) + +#### If you want to, you can create a configuration that lets you update the changes directly without restarting (in most cases) + +1. Go to `Project Settings` > `Artifacts` and create a new empty artifact +2. Add `compile output` into your `.jar` file +3. Change the output directory to the `modules` directory (it should be located in your runtime folder. if not, create + one.) +4. Apply the settings and create a new `Application`-configuration +5. Change the main-class to `xyz.sheepstar.core.SheepstarCore` +6. Click on `Modify options` > `Add before launch task` > `Build artifact` and choose your created artifact +7. Change the working directory to your runtime folder +8. Add `-cf config.json` to your program arguments +9. Ready! Click on the debug-icon to start your module, make a change and click on the build-icon to try it \ No newline at end of file diff --git a/SheepstarCoreV1/pom.xml b/SheepstarCoreV1/pom.xml new file mode 100644 index 0000000..2fae08b --- /dev/null +++ b/SheepstarCoreV1/pom.xml @@ -0,0 +1,177 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>xyz.sheepstar</groupId> + <artifactId>SheepstarCore</artifactId> + <version>beta1.0.2</version> + + <properties> + <maven.compiler.source>8</maven.compiler.source> + <maven.compiler.target>8</maven.compiler.target> + </properties> + + <repositories> + <repository> + <id>central</id> + <name>bintray</name> + <url>https://jcenter.bintray.com</url> + </repository> + <repository> + <id>dv8tion</id> + <name>m2-dv8tion</name> + <url>https://m2.dv8tion.net/releases</url> + </repository> + <repository> + <id>jitpack</id> + <url>https://jitpack.io</url> + </repository> + <repository> + <id>maven_central</id> + <name>Maven Central</name> + <url>https://repo.maven.apache.org/maven2/</url> + </repository> + </repositories> + + <build> + <plugins> + <plugin> + <artifactId>maven-assembly-plugin</artifactId> + <configuration> + <archive> + <manifest> + <mainClass>xyz.sheepstar.core.SheepstarCore</mainClass> + </manifest> + </archive> + <descriptorRefs> + <descriptorRef>jar-with-dependencies</descriptorRef> + </descriptorRefs> + </configuration> + </plugin> + </plugins> + </build> + + <dependencies> + <!-- SQLToolkit for MySQL--> + <dependency> + <groupId>com.github.gnmyt</groupId> + <artifactId>sqltoolkit</artifactId> + <version>v2.0.1</version> + <exclusions> + <exclusion> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-simple</artifactId> + </exclusion> + </exclusions> + </dependency> + + <!-- JDA (The bot itself) --> + <dependency> + <groupId>net.dv8tion</groupId> + <artifactId>JDA</artifactId> + <version>4.4.0_350</version> + </dependency> + + <!-- Commons CLI (apache-cli) --> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>1.4</version> + </dependency> + + <!-- Commons IO --> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + <version>2.7</version> + </dependency> + + <!-- Commons lang3 --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.12.0</version> + </dependency> + + <!-- Logger API (api) --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + <version>1.7.32</version> + </dependency> + + <!-- Logger API (log4j12) --> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-log4j12</artifactId> + <version>1.7.32</version> + </dependency> + + <!-- Logger API Extras --> + <dependency> + <groupId>log4j</groupId> + <artifactId>apache-log4j-extras</artifactId> + <version>1.2.17</version> + </dependency> + + <!-- Colorful console log --> + <dependency> + <groupId>com.jcabi</groupId> + <artifactId>jcabi-log</artifactId> + <version>0.20.1</version> + </dependency> + + <!-- FasterXML for YAML Configurations --> + <dependency> + <groupId>com.fasterxml.jackson.dataformat</groupId> + <artifactId>jackson-dataformat-yaml</artifactId> + <version>2.13.0</version> + </dependency> + + <!-- FasterXML Databind --> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-databind</artifactId> + <version>2.13.0</version> + </dependency> + + <!-- HTTP Client --> + <dependency> + <groupId>com.squareup.okhttp3</groupId> + <artifactId>okhttp</artifactId> + <version>4.9.2</version> + </dependency> + + <!-- Guava --> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>31.0.1-jre</version> + </dependency> + + <!-- Reflections Library --> + <dependency> + <groupId>org.reflections</groupId> + <artifactId>reflections</artifactId> + <version>0.10.2</version> + </dependency> + + <!-- Simple time formatter --> + <dependency> + <groupId>org.ocpsoft.prettytime</groupId> + <artifactId>prettytime</artifactId> + <version>5.0.2.Final</version> + </dependency> + + <!-- Discord webhook library --> + <dependency> + <groupId>club.minnced</groupId> + <artifactId>discord-webhooks</artifactId> + <version>0.7.2</version> + </dependency> + + </dependencies> + +</project> \ No newline at end of file diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/SheepstarCore.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/SheepstarCore.java new file mode 100644 index 0000000..ac0af0d --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/SheepstarCore.java @@ -0,0 +1,78 @@ +package xyz.sheepstar.core; + +import xyz.sheepstar.core.commands.console.*; +import xyz.sheepstar.core.commands.general.HelpCommand; +import xyz.sheepstar.core.commands.general.*; +import xyz.sheepstar.util.SheepstarImpl; + +public class SheepstarCore { + + private static SheepstarImpl sheepstar; + + public static void main(String[] args) throws Exception { + sheepstar = new SheepstarImpl(args); + sheepstar.init(); + + registerConsoleCommands(); + registerGeneralCommands(); + + Thread.sleep(5000); + sheepstar.finish(); + } + + /** + * Registers all general commands (all commands in the general-package) + */ + public static void registerGeneralCommands() { + + sheepstar.registerGeneralCommand(new ListSettingsCommand()); + sheepstar.registerGeneralCommand(new SetSettingCommand()); + + sheepstar.registerGeneralCommand(new BuyCommand()); + sheepstar.registerGeneralCommand(new ShopCommand()); + sheepstar.registerGeneralCommand(new SwitchLanguageCommand()); + sheepstar.registerGeneralCommand(new ShowCoinsCommand()); + sheepstar.registerGeneralCommand(new HelpCommand()); + sheepstar.registerGeneralCommand(new ListCommandsCommand()); + sheepstar.registerGeneralCommand(new InfoCommand()); + + sheepstar.registerGeneralCommand(new DisableModuleCommand()); + sheepstar.registerGeneralCommand(new EnableModuleCommand()); + + sheepstar.registerGeneralCommand(new ShowPrefixCommand()); + + sheepstar.registerGeneralCommand(new RedeemCommand()); + + sheepstar.registerGeneralCommand(new PingCommand()); + } + + /** + * Registers all console commands (all commands in the console package) + */ + public static void registerConsoleCommands() { + sheepstar.getConsoleManager().register(new GetSettingCommand()); + sheepstar.getConsoleManager().register(new GetSettingInfoCommand()); + + sheepstar.getConsoleManager().register(new InsertSettingInfoCommand()); + sheepstar.getConsoleManager().register(new UpdateSettingCommand()); + + sheepstar.getConsoleManager().register(new xyz.sheepstar.core.commands.console.HelpCommand()); + + sheepstar.getConsoleManager().register(new LoadModuleCommand()); + + sheepstar.getConsoleManager().register(new QueryCommand()); + + sheepstar.getConsoleManager().register(new ShutdownCommand()); + + sheepstar.getConsoleManager().register(new TranslationCommand()); + } + + /** + * Gets the sheepstar api object + * + * @return the sheepstar api object + */ + public static SheepstarImpl getSheepstar() { + return sheepstar; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingCommand.java new file mode 100644 index 0000000..5763b91 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingCommand.java @@ -0,0 +1,37 @@ +package xyz.sheepstar.core.commands.console; + +import net.dv8tion.jda.api.entities.Guild; +import org.slf4j.Logger; +import xyz.sheepstar.util.console.ConsoleCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.Arrays; +import java.util.List; + +public class GetSettingCommand extends ConsoleCommand { + + private final Logger LOG = LogManager.getLog(GetSettingCommand.class); + + @Override + public List<String> getAlias() { + return Arrays.asList("getsetting", "gsg", "gst"); + } + + @Override + public void usage() { + usage("moduleName", -1, true); + usage("guildID", -1, true); + usage("setting", -1, true); + } + + @Override + public void onExecute(String[] args) { + Guild guild = api.getJDA().getGuildById(args[1]); + if (guild == null) { + LOG.error("The guild does not exist"); + return; + } + String setting = api.getBotManager().getSettingsManager().getSetting(guild, args[0], args[2]).toString(); + LOG.info("The setting {} of the guild {} has got the value {}", args[2], guild.getName(), setting); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingInfoCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingInfoCommand.java new file mode 100644 index 0000000..3a3b93d --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/GetSettingInfoCommand.java @@ -0,0 +1,35 @@ +package xyz.sheepstar.core.commands.console; + +import org.slf4j.Logger; +import xyz.sheepstar.util.console.ConsoleCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.Arrays; +import java.util.List; + +public class GetSettingInfoCommand extends ConsoleCommand { + + private final Logger LOG = LogManager.getLog(GetSettingInfoCommand.class); + + @Override + public List<String> getAlias() { + return Arrays.asList("gsettingsinfo", "getsettingsinfo", "gsi", "si"); + } + + @Override + public void usage() { + usage("moduleName", -1, true); + usage("setting", -1, true); + } + + @Override + public void onExecute(String[] args) { + if (!api.getBotManager().getSettingsInfoManager().existsInfo(args[0], args[1])) { + LOG.error("The provided info does not exists"); + return; + } + String description = api.getBotManager().getSettingsInfoManager().getDescription(args[0], args[1]); + String defaultValue = api.getBotManager().getSettingsInfoManager().getDefaultValue(args[0], args[1]); + LOG.info("The description of the info says {} and the default value says {}", description, defaultValue); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/HelpCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/HelpCommand.java new file mode 100644 index 0000000..15ed030 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/HelpCommand.java @@ -0,0 +1,28 @@ +package xyz.sheepstar.core.commands.console; + +import org.slf4j.Logger; +import xyz.sheepstar.util.console.ConsoleCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.Arrays; +import java.util.List; + +public class HelpCommand extends ConsoleCommand { + + private final Logger LOG = LogManager.getLog(HelpCommand.class); + + @Override + public List<String> getAlias() { + return Arrays.asList("help", "listcommands", "commands"); + } + + @Override + public void onExecute(String[] args) { + StringBuilder help = new StringBuilder(); + for (ConsoleCommand command : api.getConsoleManager().getRegisteredCommands()) { + if (!help.toString().isEmpty()) help.append(" "); + help.append(command.getAlias().get(0)); + } + LOG.info("Current commands available: {}", help); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/InsertSettingInfoCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/InsertSettingInfoCommand.java new file mode 100644 index 0000000..2d8dd8e --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/InsertSettingInfoCommand.java @@ -0,0 +1,33 @@ +package xyz.sheepstar.core.commands.console; + +import org.slf4j.Logger; +import xyz.sheepstar.util.console.ConsoleCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.Arrays; +import java.util.List; + +public class InsertSettingInfoCommand extends ConsoleCommand { + + private final Logger LOG = LogManager.getLog(InsertSettingInfoCommand.class); + + @Override + public List<String> getAlias() { + return Arrays.asList("isettingsinfo", "insertsettingsinfo", "isi"); + } + + @Override + public void usage() { + usage("moduleName", -1, true); + usage("settingString", -1, true); + usage("descriptionString", -1, true); + usage("defaultValue", -1, true); + usage("allowedValues", -1, true); + } + + @Override + public void onExecute(String[] args) { + api.getBotManager().getSettingsInfoManager().createInfo(args[0], args[1], args[2], args[3], args[4]); + LOG.info("The info got successfully created"); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/LoadModuleCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/LoadModuleCommand.java new file mode 100644 index 0000000..fd8e937 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/LoadModuleCommand.java @@ -0,0 +1,25 @@ +package xyz.sheepstar.core.commands.console; + + +import xyz.sheepstar.util.console.ConsoleCommand; + +import java.util.Arrays; +import java.util.List; + +public class LoadModuleCommand extends ConsoleCommand { + + @Override + public List<String> getAlias() { + return Arrays.asList("enable", "load"); + } + + @Override + public void usage() { + usage("moduleName", -1, true); + } + + @Override + public void onExecute(String[] args) { + api.getModuleManager().loadModule(args[0] + ".jar"); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/QueryCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/QueryCommand.java new file mode 100644 index 0000000..c2cd172 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/QueryCommand.java @@ -0,0 +1,43 @@ +package xyz.sheepstar.core.commands.console; + +import org.slf4j.Logger; +import xyz.sheepstar.util.console.ConsoleCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +public class QueryCommand extends ConsoleCommand { + + private final Logger LOG = LogManager.getLog(QueryCommand.class); + + @Override + public List<String> getAlias() { + return Arrays.asList("query", "result", "runquery"); + } + + @Override + public void onExecute(String[] args) { + if (args.length == 0) { + LOG.error("You need to provide a query"); + return; + } + StringBuilder query = new StringBuilder(); + for (String current : args) { + if (!query.toString().isEmpty()) query.append(" "); + query.append(current); + } + ArrayList<HashMap<String, Object>> result = api.getDatabase().getResult(query.toString()).getList(); + + System.out.println("-=============== QUERY START ===============-"); + result.forEach((map) -> { + System.out.println("--============= RESULT START ==============--"); + map.forEach((key, val) -> System.out.println(key + ": " + val)); + System.out.println("--============== RESULT END ===============--"); + }); + System.out.println("-============== QUERY END ==================-"); + + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/ShutdownCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/ShutdownCommand.java new file mode 100644 index 0000000..2957716 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/ShutdownCommand.java @@ -0,0 +1,28 @@ +package xyz.sheepstar.core.commands.console; + +import xyz.sheepstar.util.console.ConsoleCommand; + +import java.util.Arrays; +import java.util.List; + +public class ShutdownCommand extends ConsoleCommand { + + @Override + public List<String> getAlias() { + return Arrays.asList("shutdown", "stop", "end", "exit"); + } + + @Override + public void onExecute(String[] args) { + StringBuilder msg = new StringBuilder("User requested a shutdown"); + if (args.length >= 1) { + msg = new StringBuilder(); + for (String current : args) { + if (!msg.toString().isEmpty()) msg.append(" "); + msg.append(current); + } + } + api.shutdown(msg.toString()); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/TranslationCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/TranslationCommand.java new file mode 100644 index 0000000..b8c9c8a --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/TranslationCommand.java @@ -0,0 +1,35 @@ +package xyz.sheepstar.core.commands.console; + +import org.slf4j.Logger; +import xyz.sheepstar.util.console.ConsoleCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.Arrays; +import java.util.List; + +public class TranslationCommand extends ConsoleCommand { + + private final Logger LOG = LogManager.getLog(TranslationCommand.class); + + @Override + public List<String> getAlias() { + return Arrays.asList("translate", "inserttranslation", "tr"); + } + + @Override + public void onExecute(String[] args) { + if (args.length <= 2) { + LOG.error("You need to provide a translationString, a language code and a translation"); + return; + } + StringBuilder translated = new StringBuilder(); + for (int i = 2; i < args.length; i++) { + if (!translated.toString().isEmpty()) translated.append(" "); + translated.append(args[i]); + } + + api.insertTranslation(args[0], args[1], translated.toString()); + LOG.info("Translation inserted successfully"); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/UpdateSettingCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/UpdateSettingCommand.java new file mode 100644 index 0000000..28c4e2c --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/console/UpdateSettingCommand.java @@ -0,0 +1,39 @@ +package xyz.sheepstar.core.commands.console; + +import net.dv8tion.jda.api.entities.Guild; +import org.slf4j.Logger; +import xyz.sheepstar.util.console.ConsoleCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.Arrays; +import java.util.List; + +public class UpdateSettingCommand extends ConsoleCommand { + + private final Logger LOG = LogManager.getLog(UpdateSettingCommand.class); + + @Override + public List<String> getAlias() { + return Arrays.asList("updatesetting", "usg", "ust"); + } + + @Override + public void usage() { + usage("moduleName", -1, true); + usage("guildID", -1, true); + usage("setting", -1, true); + usage("value", -1, true); + } + + @Override + public void onExecute(String[] args) { + Guild guild = api.getJDA().getGuildById(args[1]); + if (guild == null) { + LOG.error("The guild does not exist"); + return; + } + api.getBotManager().getSettingsManager().updateSetting(guild, args[0], args[2], args[3]); + LOG.info("Setting updated successfully"); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/BuyCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/BuyCommand.java new file mode 100644 index 0000000..8bb694f --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/BuyCommand.java @@ -0,0 +1,47 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.manager.sql.GuildManager; +import xyz.sheepstar.util.bot.permission.PermissionNode; +import xyz.sheepstar.util.http.client.entities.Article; +import xyz.sheepstar.util.http.client.objects.ArticleObject; +import xyz.sheepstar.util.http.client.objects.ShopObject; + +@CommandMeta(aliases = {"buy", "buyarticle"}, permission = PermissionNode.ADMINISTRATOR, description = "Buys an article") +public class BuyCommand extends GeneralGuildCommand { + + private final ShopObject itemManager = api.getShop(); + private final ArticleObject articleManager = api.getArticles(); + private final GuildManager guildManager = api.getBotManager().getGuildManager(); + + @Override + public void usage() { + usage("article", "The ID of the article you want to buy").required(true).add(); + usage("moduleName", "The module you want to use to buy this item").add(); + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + Article article = articleManager.findArticle(args.exists("moduleName") ? moduleName : "main", args.getString("article")).complete(); + + if (article == null) throw new PublicCommandException("bot.article.not_existing"); + + int currentMoney = guildManager.getCoinsInt(event.getGuild()); + int neededMoney = article.getArticlePrice(); + + if (currentMoney < neededMoney) throw new PublicCommandException("bot.not_enough_money"); + + Integer code = itemManager.activateItem(article.getID() + "", event.getGuild()).complete(); + + if (code == 400) throw new PublicCommandException("bot.article.reached_limit"); + + guildManager.updateCoins(event.getGuild(), String.valueOf(currentMoney - neededMoney)); + + event.success("bot.article_activated", article.getArticleName()); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/DisableModuleCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/DisableModuleCommand.java new file mode 100644 index 0000000..ee53feb --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/DisableModuleCommand.java @@ -0,0 +1,20 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +@CommandMeta(aliases = "module", subAliases = "disable", permission = PermissionNode.ADMINISTRATOR, description = "Disables a module") +public class DisableModuleCommand extends GeneralGuildCommand { + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + if (!moduleManager.isEnabled(event.getGuild(), moduleName.toLowerCase())) + throw new PublicCommandException("bot.module.not_enabled"); + moduleManager.disableModule(event.getGuild(), moduleName.toLowerCase()); + event.success("bot.module_disabled"); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/EnableModuleCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/EnableModuleCommand.java new file mode 100644 index 0000000..58f9c15 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/EnableModuleCommand.java @@ -0,0 +1,33 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +@CommandMeta(aliases = "module", subAliases = "enable", permission = PermissionNode.ADMINISTRATOR, description = "Enables a module") +public class EnableModuleCommand extends GeneralGuildCommand { + + @Override + public void generalUsage() { + usage("prefix", "The prefix you want to use in this module").add(); + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + if (moduleManager.isEnabled(event.getGuild(), moduleName.toLowerCase())) + throw new PublicCommandException("bot.module.already_enabled"); + + if (api.getModuleManager().getActivated_modules().get(moduleName) == null) + throw new PublicCommandException("bot.module.does_not_exist"); + + String prefix = args.exists("prefix") ? args.getString("prefix").replace(" ", "") : "!"; + if (prefix.length() > 5) prefix = prefix.substring(0, 5); + + moduleManager.enableModule(event.getGuild(), moduleName.toLowerCase(), prefix); + + event.success("bot.module_enabled", moduleName.toLowerCase(), prefix.toLowerCase()); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/HelpCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/HelpCommand.java new file mode 100644 index 0000000..b1f10ff --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/HelpCommand.java @@ -0,0 +1,21 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; + +@CommandMeta(aliases = "help", description = "Shows a quick help of the sheepstar bot") +public class HelpCommand extends GeneralGuildCommand { + + @Override + public void usage() { + + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + event.primary("bot.help"); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/InfoCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/InfoCommand.java new file mode 100644 index 0000000..aa8972b --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/InfoCommand.java @@ -0,0 +1,20 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; + +@CommandMeta(aliases = "info", description = "Shows the info of the bot") +public class InfoCommand extends GeneralGuildCommand { + + @Override + public void usage() { + + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + event.primary("bot.info"); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListCommandsCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListCommandsCommand.java new file mode 100644 index 0000000..b88e5d1 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListCommandsCommand.java @@ -0,0 +1,60 @@ +package xyz.sheepstar.core.commands.general; + +import com.google.common.base.CaseFormat; +import xyz.sheepstar.util.bot.builder.message.MessageField; +import xyz.sheepstar.util.bot.builder.message.MessageType; +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildCommand; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.internal.manager.ListenerManager; + +import java.util.ArrayList; +import java.util.Arrays; + +@CommandMeta(aliases = "commands", description = "Shows you all commands of this bot") +public class ListCommandsCommand extends GeneralGuildCommand { + + ListenerManager listenerManager = api.getListenerManager(); + + @Override + public void usage() { + usage("moduleName", "The name of the module you want to get commands from").add(); + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + ArrayList<MessageField> fields = new ArrayList<>(); + + for (GuildCommand command : listenerManager.getCommands()) { + CommandMeta meta = command.getClass().getAnnotation(CommandMeta.class); + + if (command instanceof GeneralGuildCommand && args.exists("moduleName")) continue; + + if (!(command instanceof GeneralGuildCommand) && !args.exists("moduleName")) continue; + + if (!(command instanceof GeneralGuildCommand) && args.exists("moduleName") + && !api.getModuleName(command.getClass().getName()).equals(args.getString("moduleName"))) continue; + + StringBuilder aliases = new StringBuilder(); + Arrays.stream(meta.aliases()).forEach(alias -> { + if (!aliases.toString().isEmpty()) aliases.append(", "); + aliases.append(alias); + }); + + fields.add(new MessageField(":gear: " + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, meta.aliases()[0] + " " + + (meta.subAliases().length >= 1 ? meta.subAliases()[0] : "")), + "**" + translate("bot.description", event.getLanguage()) + "**: " + meta.description(), + "**" + translate("bot.aliases", event.getLanguage()) + + "**: " + aliases + " " + (meta.subAliases().length >= 1 ? meta.subAliases()[0] : ""))); + } + + if (fields.isEmpty()) + fields.add(new MessageField(":warning: " + translate("bot.not_found", event.getLanguage()), + translate("bot.module_not_found", event.getLanguage()))); + + event.custom(MessageType.PRIMARY, "bot.commands", fields); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListSettingsCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListSettingsCommand.java new file mode 100644 index 0000000..bba6be8 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ListSettingsCommand.java @@ -0,0 +1,35 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.builder.message.MessageField; +import xyz.sheepstar.util.bot.builder.message.MessageType; +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.manager.sql.SettingsInfoManager; +import xyz.sheepstar.util.bot.manager.sql.SettingsManager; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +import java.util.ArrayList; + +@CommandMeta(aliases = {"settings", "listsettings"}, permission = PermissionNode.ADMINISTRATOR, description = "Lists all settings from the current guild") +public class ListSettingsCommand extends GeneralGuildCommand { + + private final SettingsManager settingsManager = api.getBotManager().getSettingsManager(); + private final SettingsInfoManager settingsInfoManager = api.getBotManager().getSettingsInfoManager(); + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + ArrayList<MessageField> fields = new ArrayList<>(); + settingsInfoManager.getSettings(moduleName).forEach(setting -> { + String value = settingsManager.getSettingString(event.getGuild(), moduleName, (String) setting.get("settingString")); + if (value.equals("yes") || value.equals("no")) value = translate("bot." + value, event.getLanguage()); + + fields.add(new MessageField(String.format(":gear: `%s`", setting.get("settingString")), + translate((String) setting.get("descriptionString"), event.getLanguage()), + translate("bot.current", event.getLanguage()) + ": **" + value + "**")); + }); + + event.custom(MessageType.PRIMARY, "bot.module_settings", fields, moduleName); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/PingCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/PingCommand.java new file mode 100644 index 0000000..91b3bbb --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/PingCommand.java @@ -0,0 +1,21 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; + +@CommandMeta(aliases = {"ping", "botping", "gwping"}, description = "Shows you the current ping of the bot") +public class PingCommand extends GeneralGuildCommand { + + @Override + public void usage() { + + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + event.primary("bot.ping", jda.getGatewayPing()); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/RedeemCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/RedeemCommand.java new file mode 100644 index 0000000..0d42275 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/RedeemCommand.java @@ -0,0 +1,36 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.permission.PermissionNode; +import xyz.sheepstar.util.http.client.entities.Gift; +import xyz.sheepstar.util.http.client.objects.ArticleObject; +import xyz.sheepstar.util.http.client.objects.GiftObject; + +@CommandMeta(aliases = "redeem", permission = PermissionNode.ADMINISTRATOR, description = "Redeems a gift code to the server") +public class RedeemCommand extends GeneralGuildCommand { + + private final GiftObject giftManager = api.getGifts(); + private final ArticleObject articleManager = api.getArticles(); + + @Override + public void usage() { + usage("giftID", "The gift code").required(true).add(); + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + Gift info = giftManager.getInfo(args.getString("giftID")).complete(); + + Integer code = giftManager.redeemGift(args.getString("giftID"), event.getGuild()).complete(); + + if (code == 400) throw new PublicCommandException("bot.article.reached_limit"); + + if (code == 404) throw new PublicCommandException("bot.gift.not_found"); + + event.success("bot.gift.redeemed_successfully", articleManager.getArticle(info.getArticleId()).complete().getArticleName()); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SetSettingCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SetSettingCommand.java new file mode 100644 index 0000000..1d03e5f --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SetSettingCommand.java @@ -0,0 +1,37 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.manager.sql.SettingsInfoManager; +import xyz.sheepstar.util.bot.manager.sql.SettingsManager; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +@CommandMeta(aliases = {"setting", "setsetting"}, permission = PermissionNode.ADMINISTRATOR, description = "Sets a setting in a guild") +public class SetSettingCommand extends GeneralGuildCommand { + + private final SettingsManager settingsManager = api.getBotManager().getSettingsManager(); + private final SettingsInfoManager settingsInfoManager = api.getBotManager().getSettingsInfoManager(); + + @Override + public void generalUsage() { + usage("setting", "The setting key").required(true).add(); + usage("value", "The setting value").required(true).add(); + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + if (!settingsInfoManager.existsInfo(moduleName, args.getString("setting"))) + throw new PublicCommandException("bot.setting.not_existing"); + + if (!settingsInfoManager.isAllowed(moduleName, args.getString("setting"), args.getString("value"))) + throw new PublicCommandException("bot.setting.value_not_allowed", + settingsInfoManager.getAllowedValuesPretty(moduleName, args.getString("setting"))); + + settingsManager.updateSetting(event.getGuild(), moduleName, args.getString("setting"), args.getString("value")); + + event.success("bot.setting_updated", args.getString("setting"), args.getString("value")); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShopCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShopCommand.java new file mode 100644 index 0000000..853764c --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShopCommand.java @@ -0,0 +1,67 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.builder.message.MessageField; +import xyz.sheepstar.util.bot.builder.message.MessageType; +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.emote.INTERN_EMOTE; +import xyz.sheepstar.util.bot.permission.PermissionNode; +import xyz.sheepstar.util.http.client.entities.Article; +import xyz.sheepstar.util.http.client.entities.ShopItem; +import xyz.sheepstar.util.http.client.objects.ArticleObject; +import xyz.sheepstar.util.http.client.objects.ShopObject; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@CommandMeta(aliases = {"shop", "listarticles"}, permission = PermissionNode.ADMINISTRATOR, description = "Shows all articles you can buy") +public class ShopCommand extends GeneralGuildCommand { + + private final ShopObject itemManager = api.getShop(); + private final ArticleObject articleManager = api.getArticles(); + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + List<Article> items = articleManager.getArticles(moduleName).complete(); + + if (items == null) throw new Exception("Could not process request"); + + ArrayList<MessageField> fields = new ArrayList<>(); + + List<ShopItem> owned_items = itemManager.getItems(event.getGuild()).complete(); + + HashMap<Integer, Integer> ownedArticles = sortOwnedArticles(owned_items); + + items.forEach(item -> { + int currentCount = ownedArticles.get(item.getID()) != null ? ownedArticles.get(item.getID()) : 0; + String bought = currentCount == item.getMaxOwnCount() ? ":white_check_mark:" : currentCount + "/" + item.getMaxOwnCount(); + + fields.add(new MessageField(String.format(":shopping_cart: `%s` | %s", item.getArticleName(), bought), item.getArticleDescription(), + translate("bot.article_id", event.getLanguage()) + ": **" + item.getArticleId() + "**", + translate("bot.article_price", event.getLanguage()) + ": **" + item.getArticlePrice() + "** " + getEmoteString(INTERN_EMOTE.STAR_COIN))); + }); + + event.custom(MessageType.PRIMARY, "bot.shop", fields, moduleName); + } + + /** + * Returns a HashMap with the article ID as key and the amount of owned articles as value + * + * @param items The list of owned items + * @return the HashMap + */ + public HashMap<Integer, Integer> sortOwnedArticles(List<ShopItem> items) { + HashMap<Integer, Integer> ownedArticles = new HashMap<>(); + items.forEach(item -> { + Integer articleID = Integer.valueOf(item.getArticleId()); + if (ownedArticles.containsKey(articleID)) { + ownedArticles.put(articleID, ownedArticles.get(articleID) + 1); + } else ownedArticles.put(articleID, 1); + }); + return ownedArticles; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowCoinsCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowCoinsCommand.java new file mode 100644 index 0000000..9703372 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowCoinsCommand.java @@ -0,0 +1,23 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.builder.message.MessageType; +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +@CommandMeta(aliases = "coins", permission = PermissionNode.ADMINISTRATOR, description = "Shows your current amount of StarCoins") +public class ShowCoinsCommand extends GeneralGuildCommand { + + @Override + public void usage() { + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + event.custom(MessageType.PRIMARY, "bot.coins.coin_status", api.getBotManager().getGuildManager().getCoins(event.getGuild())) + .addLink(translate("bot.coins.buy_more", event.getLanguage()), "https://dash.sheepstar.xyz/shop") + .send(); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowPrefixCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowPrefixCommand.java new file mode 100644 index 0000000..ba52ad5 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/ShowPrefixCommand.java @@ -0,0 +1,33 @@ +package xyz.sheepstar.core.commands.general; + +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +@CommandMeta(aliases = "module", subAliases = "prefix", permission = PermissionNode.ADMINISTRATOR, + description = "Shows/updates a prefix from a module") +public class ShowPrefixCommand extends GeneralGuildCommand { + + @Override + public void generalUsage() { + usage("newPrefix", "Changes the prefix of the module").add(); + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + if (!moduleManager.isEnabled(event.getGuild(), moduleName)) + throw new PublicCommandException("bot.module.not_enabled"); + if (args.exists("newPrefix")) { + String prefix = args.getString("newPrefix"); + if (prefix.length() > 5) prefix = prefix.substring(0, 5); + + moduleManager.updatePrefix(event.getGuild(), moduleName.toLowerCase(), prefix); + event.success("bot.module.prefix_updated", moduleName.toLowerCase(), prefix); + } else { + event.primary("bot.module.prefix", moduleName.toLowerCase(), moduleManager.getPrefix(event.getGuild(), moduleName.toLowerCase())); + } + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SwitchLanguageCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SwitchLanguageCommand.java new file mode 100644 index 0000000..40483ef --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/core/commands/general/SwitchLanguageCommand.java @@ -0,0 +1,57 @@ +package xyz.sheepstar.core.commands.general; + +import net.dv8tion.jda.api.entities.Emoji; +import net.dv8tion.jda.api.interactions.components.ButtonStyle; +import xyz.sheepstar.util.bot.builder.message.DefaultResponseBuilder; +import xyz.sheepstar.util.bot.builder.message.MessageType; +import xyz.sheepstar.util.bot.builder.message.Translate; +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +import java.util.HashMap; + +@CommandMeta(aliases = "language", permission = PermissionNode.ADMINISTRATOR, description = "Changes the language of the bot") +public class SwitchLanguageCommand extends GeneralGuildCommand { + + private final HashMap<String, Emoji> languages = new HashMap<>(); + + public SwitchLanguageCommand() { + api.getBotManager().getLanguageManager().getLanguages().forEach(language -> + languages.put((String) language.get("code"), Emoji.fromUnicode((String) language.get("emoji")))); + } + + @Override + public void usage() { + } + + public DefaultResponseBuilder sendLanguageMessage(GuildEventController event) { + DefaultResponseBuilder builder = event.custom(MessageType.PRIMARY, "bot.language_update", "null", Translate.ONLY_TITLE); + languages.forEach((language, emoji) -> + builder.addButton(language.equals(getLanguage(event.getGuild())) ? ButtonStyle.PRIMARY : ButtonStyle.SECONDARY, language, emoji)); + + return builder; + } + + @Override + public void execute(GuildEventController event, Arguments args, String moduleName) throws Exception { + sendLanguageMessage(event) + .withDescription(translate("bot.choose_language", event.getLanguage())) + .send(); + } + + @Override + public void buttonClick(GuildEventController event, String id) throws Exception { + if (!languages.containsKey(id)) throw new PublicCommandException("bot.unknown_language"); + + api.getBotManager().getGuildManager().updateLanguage(event.getGuild(), id); + + sendLanguageMessage(event) + .withDescription(translate("bot.language_updated", event.getLanguage(), + api.getBotManager().getLanguageManager().getName(id.toLowerCase()))) + .send(); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/Sheepstar.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/Sheepstar.java new file mode 100644 index 0000000..b0e5ea7 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/Sheepstar.java @@ -0,0 +1,62 @@ +package xyz.sheepstar.util; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.User; +import xyz.sheepstar.util.bot.command.GuildCommand; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.console.ConsoleManager; +import xyz.sheepstar.util.http.client.Requester; +import xyz.sheepstar.util.http.client.objects.ArticleObject; +import xyz.sheepstar.util.http.client.objects.GiftObject; +import xyz.sheepstar.util.http.client.objects.ShopObject; +import xyz.sheepstar.util.validation.trigger.TriggerValidator; + +import java.io.File; + +public interface Sheepstar { + + void shutdown(); + + void shutdown(String message); + + void shutdown(String message, int code); + + String translate(String translationString, String languageCode, Object... values); + + String translate(String translationString, Object... values); + + void insertTranslation(String translationString, String languageCode, String translation); + + boolean isOwner(User user); + + boolean isSupporter(User user); + + JDA getJDA(); + + JDA getMainJDA(); + + File getFromCache(String fileName); + + String getModuleName(String className); + + void registerListener(String moduleName, Object listener); + + void registerCommand(String moduleName, GuildCommand command); + + void registerGeneralCommand(GeneralGuildCommand command); + + ConsoleManager getConsoleManager(); + + Requester getRequester(); + + boolean isDebugModeEnabled(); + + ShopObject getShop(); + + ArticleObject getArticles(); + + GiftObject getGifts(); + + TriggerValidator getTriggerValidator(); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/SheepstarImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/SheepstarImpl.java new file mode 100644 index 0000000..fa1cbd2 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/SheepstarImpl.java @@ -0,0 +1,488 @@ +package xyz.sheepstar.util; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.User; +import net.dv8tion.jda.api.events.ReadyEvent; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import net.dv8tion.jda.api.requests.restaction.CommandListUpdateAction; +import net.dv8tion.jda.api.sharding.DefaultShardManagerBuilder; +import net.dv8tion.jda.api.sharding.ShardManager; +import org.jetbrains.annotations.NotNull; +import org.slf4j.Logger; +import xyz.sheepstar.util.action.ScheduledExecutorPool; +import xyz.sheepstar.util.bot.command.GuildCommand; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.manager.BotManager; +import xyz.sheepstar.util.configuration.DatabaseConfiguration; +import xyz.sheepstar.util.configuration.SheepstarConfiguration; +import xyz.sheepstar.util.console.ConsoleManager; +import xyz.sheepstar.util.event.api.EventManager; +import xyz.sheepstar.util.http.client.Requester; +import xyz.sheepstar.util.http.client.objects.ArticleObject; +import xyz.sheepstar.util.http.client.objects.GiftObject; +import xyz.sheepstar.util.http.client.objects.ShopObject; +import xyz.sheepstar.util.http.client.objects.internal.ArticleObjectImpl; +import xyz.sheepstar.util.http.client.objects.internal.GiftObjectImpl; +import xyz.sheepstar.util.http.client.objects.internal.ShopObjectImpl; +import xyz.sheepstar.util.http.server.WebServer; +import xyz.sheepstar.util.internal.manager.CacheManager; +import xyz.sheepstar.util.internal.manager.ConfigurationManager; +import xyz.sheepstar.util.internal.manager.ListenerManager; +import xyz.sheepstar.util.internal.manager.OptionManager; +import xyz.sheepstar.util.log.LogManager; +import xyz.sheepstar.util.module.ModuleManager; +import xyz.sheepstar.util.sql.DatabaseCheckerThread; +import xyz.sheepstar.util.sql.SheepDatabase; +import xyz.sheepstar.util.validation.trigger.TriggerValidator; + +import javax.security.auth.login.LoginException; +import java.io.File; +import java.util.Random; + +public class SheepstarImpl extends ListenerAdapter implements Sheepstar { + + private final Logger LOG = LogManager.getLog(SheepstarImpl.class); + + private final String[] args; + private final ScheduledExecutorPool scheduledExecutorPool = new ScheduledExecutorPool(); + private final TriggerValidator triggerValidator = new TriggerValidator(); + private final EventManager eventManager = new EventManager(this); + + private SheepDatabase database; + private ModuleManager moduleManager; + + private ConfigurationManager configurationManager; + private CacheManager cacheManager; + private OptionManager optionManager; + private ListenerManager listenerManager; + + private BotManager botManager; + private WebServer webServer; + private Requester requester; + private ConsoleManager consoleManager; + private ShardManager shardManager; + private int readyShards = 0; + + private boolean debugModeEnabled = false; + + /** + * Basic constructor of the Sheepstar instance + * + * @param args The program arguments + */ + public SheepstarImpl(String[] args) { + this.args = args; + } + + /** + * Initializes sheepstar + */ + public void init() { + LOG.info("Starting Sheepstar..."); + + optionManager = new OptionManager(this, args); + optionManager.parseDefault(); + debugModeEnabled = optionManager.hasOption("debugMode"); + + LOG.info("Loading configuration...."); + configurationManager = new ConfigurationManager(this, new File(optionManager.getOptionValue("cf"))); + LOG.info("Configuration file {} loaded successfully", optionManager.getOptionValue("cf")); + + moduleManager = new ModuleManager(getConfig().getModuleDirectory(), this); + + listenerManager = new ListenerManager(this); + + initExecutionPools(); + + connectDatabase(); + + LOG.info("Starting the JDA instance"); + setupJDA(); + LOG.info("Starting the internal http webserver"); + setupHttp(); + + LOG.info("Waiting for the JDA instance to start"); + + while (readyShards != shardManager.getShardsTotal()) { + try { + Thread.sleep(1000); + } catch (InterruptedException ignored) { + } + } + + LOG.info("Successfully started the JDA instance"); + + requester = new Requester(this); + botManager = new BotManager(this); + consoleManager = new ConsoleManager(this); + + LOG.info("Downloading files to cache"); + cacheManager = new CacheManager(this); + cacheManager.loadDefaultCacheElements(); + LOG.info("Successfully downloaded all files to cache"); + + LOG.info("Loading modules..."); + moduleManager.loadAllModules(); + } + + @Override + public void onReady(@NotNull ReadyEvent event) { + readyShards++; + } + + /** + * Finishes up the work + */ + public void finish() { + LOG.info("Finishing up..."); + + String debugGuild = getConfig().getCommandConfiguration().getDebugGuild(); + + CommandListUpdateAction updateAction = debugGuild.isEmpty() ? getMainJDA().updateCommands() + : getMainJDA().getGuildById(debugGuild).updateCommands(); + + updateAction.addCommands(listenerManager.rewriteCommandsToData()).complete(); + + listenerManager.updateCommandMetaInternal(); + + LOG.info("Finished up loading"); + } + + /** + * Initializes the scheduled executor pool + */ + public void initExecutionPools() { + getConfig().getPools().forEach(pool -> scheduledExecutorPool.createPool(pool.getPoolName(), pool.getCorePoolSize())); + } + + /** + * Shuts down the api with no reason + */ + public void shutdown() { + shutdown("No reason provided", 0); + } + + /** + * Shuts down the api with a message + * + * @param message The message you want to provide + */ + public void shutdown(String message) { + shutdown(message, 0); + } + + /** + * Shuts down the api with a message and a code + * + * @param message The message you want to provide + * @param code The code you want to provide + */ + public void shutdown(String message, int code) { + LOG.info("Shutting down... Reason: " + message); + try { + getJDA().shutdown(); + } catch (NullPointerException ignored) { + } + System.exit(code); + } + + /** + * Connects to the database with the login parameters provided in the file + */ + private void connectDatabase() { + DatabaseConfiguration config = getConfig().getDatabaseConfiguration(); + database = new SheepDatabase(this, config.getHostname(), config.getUsername(), config.getPassword(), config.getDatabase()); + database.connect(); + if (!database.isConnected()) + shutdown("Could not connect to database, please check your config."); + new DatabaseCheckerThread(this).start(); + } + + /** + * Initializes the JDA + */ + private void setupJDA() { + try { + shardManager = DefaultShardManagerBuilder.createDefault(getConfig().getToken()) + .addEventListeners(this) + .setShardsTotal(Integer.parseInt(getOptionManager().getOptionValue("shardAmount"))).build(); + } catch (LoginException e) { + shutdown("Could not create a JDA instance: " + e.getMessage()); + } + } + + /** + * Creates and starts the Http server + */ + private void setupHttp() { + webServer = new WebServer(); + webServer.start(); + } + + /** + * Gets the event manager + * + * @return the event manager + */ + public EventManager getEventManager() { + return eventManager; + } + + /** + * Gets the database + * + * @return the database + */ + public SheepDatabase getDatabase() { + return database; + } + + /** + * Gets the module manager + * + * @return the module manager + */ + public ModuleManager getModuleManager() { + return moduleManager; + } + + /** + * Gets the bot manager + * + * @return the bot manager + */ + public BotManager getBotManager() { + return botManager; + } + + /** + * Gets a translation from a string + * + * @param translationString The translation code/string + * @param languageCode The language you want to get the translation from + * @param values The objects you want to add to your translation + * @return the translation + */ + public String translate(String translationString, String languageCode, Object... values) { + return getBotManager().getTranslationManager().getTranslation(translationString, languageCode, values); + } + + /** + * Gets a translation from a string with the english language code + * + * @param translationString The translation code/string + * @param values The objects you want to add to your translation + * @return the translation + */ + public String translate(String translationString, Object... values) { + return translate(translationString, "en", values); + } + + /** + * Creates a translation + * + * @param translationString The translation code/string + * @param languageCode The language code + * @param translation The translation itself + */ + public void insertTranslation(String translationString, String languageCode, String translation) { + getBotManager().getTranslationManager().translate(translationString, languageCode, translation); + } + + /** + * Gets a random JDA instance + * + * @return the jda instance + */ + public JDA getJDA() { + return shardManager.getShards().get(new Random().nextInt(shardManager.getShardsTotal())); + } + + /** + * Gets the main jda instance + * + * @return the main jda instance + */ + public JDA getMainJDA() { + return shardManager.getShards().get(0); + } + + /** + * Gets the shard manager + * + * @return the shard manager + */ + public ShardManager getShardManager() { + return shardManager; + } + + /** + * Gets the console manager + * + * @return the console manager + */ + public ConsoleManager getConsoleManager() { + return consoleManager; + } + + /** + * Gets the http requester + * + * @return the requester + */ + public Requester getRequester() { + return requester; + } + + + /** + * Gets the sheepstar configuration + * + * @return the sheepstar configuration + */ + public SheepstarConfiguration getConfig() { + return configurationManager.getConfiguration(); + } + + /** + * Checks if the user is in the list of owners + * + * @param user The user you want to check + * @return <code>true</code> if the member is an owner of the bot, otherwise <code>false</code> + */ + public boolean isOwner(User user) { + for (String existingOwner : getConfig().getPermissionConfiguration().getBotOwner()) + if (user.getId().equals(existingOwner)) return true; + return false; + } + + /** + * Checks if the user has the supporter/moderator role on the sheepstar discord + * + * @param user The user you want to check + * @return <code>true</code> if the member is a supporter, otherwise <code>false</code> + */ + public boolean isSupporter(User user) { + try { + return getJDA().getGuildById(getConfig().getPermissionConfiguration().getSupporter().getGuildID()).retrieveMember(user).complete() + .getRoles().contains(getJDA().getRoleById(getConfig().getPermissionConfiguration().getSupporter().getRoleID())); + } catch (Exception e) { + return false; + } + } + + /** + * Gets a file from the cache + * + * @param fileName The file you want to get + * @return the file from the cache + */ + public File getFromCache(String fileName) { + return cacheManager.getFile(fileName); + } + + /** + * Downloads an asset directly to the cache + * + * @param url The url you want to get the asset from + * @param fileName The name of the file + */ + public void downloadCachedElement(String url, String fileName) { + cacheManager.downloadAsset(url, fileName); + } + + /** + * Gets the option manager + * + * @return the option manager + */ + public OptionManager getOptionManager() { + return optionManager; + } + + /** + * Gets the name of the module by a class name + * + * @param className The name of the class you want to get the module from + * @return the name of the module + */ + public String getModuleName(String className) { + return listenerManager.getModuleName(className); + } + + /** + * Gets the listener manager + * + * @return the listener manager + */ + public ListenerManager getListenerManager() { + return listenerManager; + } + + /** + * Registers a listener + * + * @param moduleName The name of the module you want to use + * @param listener The listener you want to register + */ + public void registerListener(String moduleName, Object listener) { + listenerManager.registerListener(moduleName, listener); + } + + /** + * Registers a command + * + * @param moduleName The name of the module you want to use + * @param command The command you want to register + */ + public void registerCommand(String moduleName, GuildCommand command) { + listenerManager.registerCommand(moduleName, command); + } + + /** + * Registers a general command + * + * @param command The general command you want to register + */ + public void registerGeneralCommand(GeneralGuildCommand command) { + listenerManager.registerGeneralCommand(command); + } + + /** + * Shows you the current value of the debug mode + * + * @return <code>true</code> if the debug mode is enabled, otherwise <code>false</code> + */ + public boolean isDebugModeEnabled() { + return debugModeEnabled; + } + + /** + * Gets the scheduler + * + * @return the scheduler + */ + public ScheduledExecutorPool getScheduledExecutorPool() { + return scheduledExecutorPool; + } + + @Override + public ShopObject getShop() { + return new ShopObjectImpl(this); + } + + @Override + public ArticleObject getArticles() { + return new ArticleObjectImpl(this); + } + + @Override + public GiftObject getGifts() { + return new GiftObjectImpl(this); + } + + @Override + public TriggerValidator getTriggerValidator() { + return triggerValidator; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/RepeatedAction.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/RepeatedAction.java new file mode 100644 index 0000000..df70c1b --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/RepeatedAction.java @@ -0,0 +1,31 @@ +package xyz.sheepstar.util.action; + +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; + +public abstract class RepeatedAction extends Thread { + + protected SheepstarImpl api = SheepstarCore.getSheepstar(); + + /** + * The time needed to re-run the specific task (in seconds) + * + * @return the needed time + */ + public abstract long time(); + + /** + * Your execution logic + */ + public abstract void execute(); + + @Override + public void run() { + execute(); + try { + Thread.sleep(time() * 1000); + } catch (InterruptedException ignored) { + } + run(); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/ScheduledExecutorPool.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/ScheduledExecutorPool.java new file mode 100644 index 0000000..d7cd65d --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/action/ScheduledExecutorPool.java @@ -0,0 +1,60 @@ +package xyz.sheepstar.util.action; + +import java.util.HashMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +public class ScheduledExecutorPool { + + private final HashMap<String, ScheduledExecutorService> executorServices = new HashMap<>(); + + /** + * Executes the given task directly + * + * @param pool The pool to execute the task in + * @param runnable The task to execute + * @return this class + */ + public ScheduledExecutorPool executeInstant(String pool, Runnable runnable) { + executorServices.get(pool).execute(runnable); + return this; + } + + /** + * Executes the given task after the given delay + * + * @param pool The pool to execute the task in + * @param runnable The task to execute + * @param delay The delay + * @param timeUnit The time unit of the delay + * @return this class + */ + public ScheduledExecutorPool executeAfter(String pool, Runnable runnable, long delay, TimeUnit timeUnit) { + executorServices.get(pool).schedule(runnable, delay, timeUnit); + return this; + } + + /** + * Shuts down the given pool + * + * @param poolName The name of the pool to shut down + * @return this class + */ + public ScheduledExecutorPool shutdownPool(String poolName) { + executorServices.get(poolName).shutdown(); + return this; + } + + /** + * Creates a new pool with the given name + * + * @param poolName The name of the pool + * @param corePoolSize The core pool size + * @return this class + */ + public ScheduledExecutorPool createPool(String poolName, int corePoolSize) { + executorServices.put(poolName, Executors.newScheduledThreadPool(corePoolSize)); + return this; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/BeautifulDescriptionBuilder.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/BeautifulDescriptionBuilder.java new file mode 100644 index 0000000..3993e5a --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/BeautifulDescriptionBuilder.java @@ -0,0 +1,68 @@ +package xyz.sheepstar.util.bot.builder.message; + +import java.util.ArrayList; +import java.util.Arrays; + +public class BeautifulDescriptionBuilder { + + public ArrayList<MessageField> fields; + + /** + * Constructor of the {@link BeautifulDescriptionBuilder} + * + * @param fields The fields you want to add as default + */ + public BeautifulDescriptionBuilder(ArrayList<MessageField> fields) { + this.fields = fields; + } + + /** + * Constructor of the {@link BeautifulDescriptionBuilder} + * + * @param fields The fields you want to add as default + */ + public BeautifulDescriptionBuilder(MessageField... fields) { + this.fields = new ArrayList<>(Arrays.asList(fields)); + } + + /** + * Constructor of the {@link BeautifulDescriptionBuilder} without any fields + */ + public BeautifulDescriptionBuilder() { + this.fields = new ArrayList<>(); + } + + /** + * Adds a new field to the list + * + * @param field The field you want to add + */ + public void addField(MessageField field) { + fields.add(field); + } + + /** + * Builds the message + * + * @return the built message + */ + public String buildDefault() { + StringBuilder fieldBuilder = new StringBuilder(); + for (MessageField field : fields) { + fieldBuilder.append("**").append(field.getTitle()).append("**").append("\n"); + for (String subField : field.getSubFields()) + fieldBuilder.append("> ").append(subField).append("\n"); + fieldBuilder.append("\n"); + } + return fieldBuilder.toString(); + } + + /** + * Gets all fields of the builder + * + * @return all fields + */ + public ArrayList<MessageField> getFields() { + return fields; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultEmbedBuilder.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultEmbedBuilder.java new file mode 100644 index 0000000..bd8a280 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultEmbedBuilder.java @@ -0,0 +1,261 @@ +package xyz.sheepstar.util.bot.builder.message; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.MessageBuilder; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.MessageEmbed; +import org.jetbrains.annotations.Nullable; + +import java.awt.*; +import java.time.temporal.TemporalAccessor; +import java.util.ArrayList; + +public class DefaultEmbedBuilder extends EmbedBuilder { + + private ArrayList<MessageField> fields = new ArrayList<>(); + + /** + * Constructor of the {@link DefaultEmbedBuilder} + * + * @param type The color of the message + */ + public DefaultEmbedBuilder(MessageType type) { + setColor(type.getColor()); + } + + /** + * Constructor of the {@link DefaultEmbedBuilder} + */ + public DefaultEmbedBuilder() { + + } + + /** + * Sets the author of the embed + * + * @param name The name of the author + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setAuthor(@Nullable String name) { + super.setAuthor(name); + return this; + } + + /** + * Sets the author of the embed + * + * @param name The name of the author + * @param url The url of the title + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setAuthor(@Nullable String name, @Nullable String url) { + super.setAuthor(name, url); + return this; + } + + /** + * Sets the author of the embed + * + * @param name The name of the author + * @param url The url of the title + * @param iconUrl The url of the icon + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setAuthor(@Nullable String name, @Nullable String url, @Nullable String iconUrl) { + super.setAuthor(name, url, iconUrl); + return this; + } + + + /** + * Sets the color of the embed + * + * @param color The new color + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setColor(@Nullable Color color) { + super.setColor(color); + return this; + } + + /** + * Sets the footer of the embed + * + * @param text The text of the footer + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setFooter(@Nullable String text) { + super.setFooter(text); + return this; + } + + /** + * Sets the footer of the embed + * + * @param text The text of the footer + * @param iconUrl The url of the icon + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setFooter(@Nullable String text, @Nullable String iconUrl) { + super.setFooter(text, iconUrl); + return this; + } + + /** + * Sets the image of the embed + * + * @param url The url of the image + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setImage(@Nullable String url) { + super.setImage(url); + return this; + } + + /** + * Sets the thumbnail of the embed + * + * @param url The url of the thumbnail + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setThumbnail(@Nullable String url) { + super.setThumbnail(url); + return this; + } + + /** + * Sets the timestamp of the embed + * + * @param temporal The timezone in the footer + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setTimestamp(@Nullable TemporalAccessor temporal) { + super.setTimestamp(temporal); + return this; + } + + /** + * Sets the title of the embed + * + * @param title The new title of the embed + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setTitle(@Nullable String title) { + super.setTitle(title); + return this; + } + + /** + * Sets the title of the embed + * + * @param title The new title of the embed + * @param url The url of the title + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder setTitle(@Nullable String title, @Nullable String url) { + super.setTitle(title, url); + return this; + } + + /** + * Adds a new blank field to the field + * + * @param inline Is the field inline? + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder addBlankField(boolean inline) { + super.addBlankField(inline); + return this; + } + + /** + * Adds a new field to the embed + * + * @param name The name of the field + * @param value The value of the field + * @param inline Is the field inline? + * @return the current {@link DefaultEmbedBuilder} instance + */ + @Override + public DefaultEmbedBuilder addField(@Nullable String name, @Nullable String value, boolean inline) { + super.addField(name, value, inline); + return this; + } + + /** + * Adds a new beautiful field + * + * @param field The field you want to add + * @return the current {@link DefaultEmbedBuilder} instance + */ + public DefaultEmbedBuilder addBField(MessageField field) { + fields.add(field); + return this; + } + + /** + * Adds a new beautiful field + * + * @param title The title of the field + * @param emote The emote of the field + * @param subFields All subfields you want to add + * @return the current {@link DefaultEmbedBuilder} instance + */ + public DefaultEmbedBuilder addBField(String title, FieldEmote emote, String... subFields) { + fields.add(new MessageField(title, emote, subFields)); + return this; + } + + /** + * Adds a new beautiful field + * + * @param title The title of the field + * @param subFields All subfields you want to add + * @return the current {@link DefaultEmbedBuilder} instance + */ + public DefaultEmbedBuilder addBField(String title, String... subFields) { + fields.add(new MessageField(title, subFields)); + return this; + } + + /** + * Sets all fields of the embed + * + * @param fields The new fields + * @return the current {@link DefaultEmbedBuilder} instance + */ + public DefaultEmbedBuilder setFields(ArrayList<MessageField> fields) { + this.fields = fields; + return this; + } + + /** + * Builds the message to an embed + * + * @return the message as an embed + */ + public MessageEmbed toEmbed() { + return this.setDescription(getDescriptionBuilder() + new BeautifulDescriptionBuilder(fields).buildDefault()).build(); + } + + /** + * Builds the message to an {@link Message} object + * + * @return the message as an {@link Message} object + */ + public Message toMessage() { + return new MessageBuilder().setEmbed(toEmbed()).build(); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultResponseBuilder.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultResponseBuilder.java new file mode 100644 index 0000000..eefd127 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/DefaultResponseBuilder.java @@ -0,0 +1,334 @@ +package xyz.sheepstar.util.bot.builder.message; + +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.MessageBuilder; +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.interactions.components.ActionRow; +import net.dv8tion.jda.api.interactions.components.Button; +import net.dv8tion.jda.api.interactions.components.ButtonStyle; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.bot.command.GuildEventController; + +import java.util.ArrayList; + +public class DefaultResponseBuilder { + + private final GuildEventController eventController; + private final Class<?> trigger; + private final ArrayList<Button> buttons = new ArrayList<>(); + private ArrayList<MessageField> fields = new ArrayList<>(); + private MessageType messageType = MessageType.PRIMARY; + private String title; + private String description; + private boolean isEphemeral = false; + + /** + * Constructor of the {@link DefaultResponseBuilder} + * + * @param eventController The {@link GuildEventController} from the listener + * @param trigger The button trigger + */ + public DefaultResponseBuilder(GuildEventController eventController, Class<?> trigger) { + this.eventController = eventController; + this.trigger = trigger; + } + + /** + * Creates the {@link DefaultResponseBuilder} with only the text channel + * <p> + * <b>Warning: This could end up in errors because some methods need the user in order to run</b> + * + * @param channel The channel in which the message should be sent + * @param buttonTrigger The trigger of the buttons + * Only needed when you want to use buttons. If not, set it to <b>null</b> + * @return the created {@link DefaultResponseBuilder} + */ + public static DefaultResponseBuilder createSimple(TextChannel channel, Class<?> buttonTrigger) { + return new DefaultResponseBuilder(new GuildEventController(null, null, channel, channel.getGuild(), buttonTrigger), buttonTrigger); + } + + /** + * Creates the {@link DefaultResponseBuilder} with only the text channel + * <p> + * <b>Warning: This could end up in errors since a channel is needed for sending the message</b> + * + * @param guild The guild you want to use + * @param buttonTrigger The trigger of the buttons + * Only needed when you want to use buttons. If not, set it to <b>null</b> + * @return the created {@link DefaultResponseBuilder} + */ + public static DefaultResponseBuilder createSimple(Guild guild, Class<?> buttonTrigger) { + return new DefaultResponseBuilder(new GuildEventController(null, null, null, guild, buttonTrigger), buttonTrigger); + } + + /** + * Creates the {@link DefaultResponseBuilder} with all needed values + * + * @param member The member that sent the message + * @param channel The channel in which you want to send the message + * @param buttonTrigger The trigger of the buttons + * Only needed when you want to use buttons. If not, set it to <b>null</b> + * @return the created {@link DefaultResponseBuilder} + */ + public static DefaultResponseBuilder createFrom(Member member, TextChannel channel, Class<?> buttonTrigger) { + return new DefaultResponseBuilder(new GuildEventController(member.getUser(), member, channel, channel.getGuild(), buttonTrigger), buttonTrigger); + } + + /** + * Creates the {@link DefaultResponseBuilder} by the {@link SlashCommandEvent} + * + * @param event The event provided from the listener + * @param buttonTrigger The trigger of the buttons + * Only needed when you want to use buttons. If not, set it to <b>null</b> + * @return the created {@link DefaultResponseBuilder} + */ + public static DefaultResponseBuilder createFrom(SlashCommandEvent event, Class<?> buttonTrigger) { + return new DefaultResponseBuilder(new GuildEventController(event.getUser(), + event.getMember(), event.getTextChannel(), event.getGuild(), buttonTrigger), buttonTrigger); + } + + /** + * Creates the {@link DefaultResponseBuilder} by the {@link GuildMessageReceivedEvent} + * + * @param event The event provided from the listener + * @param buttonTrigger The trigger of the buttons + * Only needed when you want to use buttons. If not, set it to <b>null</b> + * @return the created {@link DefaultResponseBuilder} + */ + public static DefaultResponseBuilder createFrom(GuildMessageReceivedEvent event, Class<?> buttonTrigger) { + return new DefaultResponseBuilder(new GuildEventController(event.getAuthor(), + event.getMember(), event.getChannel(), event.getGuild(), buttonTrigger), buttonTrigger); + } + + /** + * Sets the color of the response + * + * @param messageType The new message color + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder withColor(MessageType messageType) { + this.messageType = messageType; + return this; + } + + /** + * Sets the title of the response + * + * @param title The new message title + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder withTitle(String title) { + this.title = title; + return this; + } + + /** + * Sets the description of the response + * + * @param description The new message description + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder withDescription(String description) { + this.description = description; + return this; + } + + /** + * Sets all fields of the response + * + * @param fields The new field array + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder withFields(ArrayList<MessageField> fields) { + this.fields = fields; + return this; + } + + /** + * Makes the message ephemeral (only visible to the sender) + * + * @param isEphemeral Should the response be ephemeral? + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder isEphemeral(boolean isEphemeral) { + this.isEphemeral = isEphemeral; + return this; + } + + /** + * Adds a new field to the response + * + * @param title The title of the message field + * @param subFields All subfields of the message field as an array + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder addField(String title, ArrayList<String> subFields) { + fields.add(new MessageField(title, subFields.toArray(new String[0]))); + return this; + } + + /** + * Adds a new field to the response with an emote + * + * @param title The title of the message field + * @param emote The emote of the message field + * @param subFields All subfields of the message field + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder addField(String title, FieldEmote emote, String... subFields) { + fields.add(new MessageField(title, emote, subFields)); + return this; + } + + /** + * Adds a new field to the response + * + * @param title The title of the message field + * @param subFields All subfields of the message field + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder addField(String title, String... subFields) { + fields.add(new MessageField(title, subFields)); + return this; + } + + /** + * Adds a button to the response + * + * @param style The style of the button you want to add + * @param id The id of the button to use it in events later + * @param text The text the button should display + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder addButton(ButtonStyle style, String id, String text) { + buttons.add(Button.of(style, trigger.getName() + "~" + id, text)); + return this; + } + + /** + * Adds a button to the response + * + * @param style The style of the button you want to add + * @param id The id of the button to use it in events later + * @param emoji The emoji the button should display + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder addButton(ButtonStyle style, String id, Emoji emoji) { + buttons.add(Button.of(style, trigger.getName() + "~" + id, emoji)); + return this; + } + + /** + * Adds a button to the response + * + * @param style The style of the button you want to add + * @param id The id of the button to use it in events later + * @param text The text the button should display + * @param emoji The emoji the button should display + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder addButton(ButtonStyle style, String id, String text, Emoji emoji) { + buttons.add(Button.of(style, trigger.getName() + "~" + id, text, emoji)); + return this; + } + + /** + * Adds a link button to the response + * + * @param text The text the button should display + * @param link The link of the button + * @return the current {@link DefaultResponseBuilder} instance + */ + public DefaultResponseBuilder addLink(String text, String link) { + buttons.add(Button.of(ButtonStyle.LINK, link, text)); + return this; + } + + /** + * Builds the response to the message + * + * @return the built message + */ + public Message build() { + MessageBuilder builder = new MessageBuilder(); + + // TODO: Let the user decide what he likes + // Currently, only embeds are available + + EmbedBuilder embed = new EmbedBuilder(); + embed.setTitle(title); + + if (description != null) { + StringBuilder descriptionBuilder = new StringBuilder(); + for (String s : description.split("\n")) + descriptionBuilder.append("> ").append(s).append("\n"); + embed.setDescription(descriptionBuilder); + } + + embed.setColor(messageType.getColor()); + + // Add all fields + if (!fields.isEmpty()) + embed.setDescription(description != null ? description : "" + new BeautifulDescriptionBuilder(fields).buildDefault()); + + // Set the action rows (buttons) + if (!buttons.isEmpty()) + builder.setActionRows(ActionRow.of(buttons)); + + // Set the author footer + if (eventController.getAuthor() != null) + embed.setFooter(SheepstarCore.getSheepstar().translate("bot.requested_by", eventController.getLanguage(), + eventController.getAuthor().getName()), eventController.getAuthor().getAvatarUrl()); + + // Only set errors ephemeral + if (messageType == MessageType.ERROR) + isEphemeral = true; + + return builder.setEmbed(embed.build()).build(); + } + + /** + * Sends the message to the guild / replies + */ + public void send() { + eventController.reply(this); + } + + /** + * Gets all buttons of the builder + * + * @return all buttons + */ + public ArrayList<Button> getButtons() { + return buttons; + } + + /** + * Gets the fields of the builder + * + * @return all message fields + */ + public ArrayList<MessageField> getFields() { + return fields; + } + + /** + * Gets the type of the message + * + * @return the message type + */ + public MessageType getMessageType() { + return messageType; + } + + /** + * Is the message ephemeral (only visible to the sender) + * + * @return <code>true</code> if the message is ephemeral, otherwise <code>false</code> + */ + public boolean isEphemeral() { + return isEphemeral; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/FieldEmote.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/FieldEmote.java new file mode 100644 index 0000000..8de0d64 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/FieldEmote.java @@ -0,0 +1,30 @@ +package xyz.sheepstar.util.bot.builder.message; + +public enum FieldEmote { + + /** + * The "information" emote + */ + INFO, + + /** + * Sets no emote as default + */ + NOTHING, + + /** + * The "successful" emote + */ + SUCCESS, + + /** + * The emote that shows up when an error happened + */ + ERROR, + + /** + * The emote that shows up when you w + */ + WARNING + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageField.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageField.java new file mode 100644 index 0000000..3a76658 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageField.java @@ -0,0 +1,87 @@ +package xyz.sheepstar.util.bot.builder.message; + +public class MessageField { + + private String title; + private String[] subFields; + private FieldEmote emote = FieldEmote.NOTHING; + + /** + * Constructor of the {@link MessageField} + * + * @param title The title of the field + * @param emote The emote which stands next to the title + * <i>This is optional</i> + * @param subFields All fields below the title + */ + public MessageField(String title, FieldEmote emote, String... subFields) { + this.title = title; + this.subFields = subFields; + this.emote = emote; + } + + /** + * Constructor of the {@link MessageField} without the emote parameter + * + * @param title The title of the field + * @param subFields All fields below the title + */ + public MessageField(String title, String... subFields) { + this.title = title; + this.subFields = subFields; + } + + /** + * Gets the title of the field + * + * @return the title of the field + */ + public String getTitle() { + return title; + } + + /** + * Sets the title of the field + * + * @param title The new title + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * Gets all subfields of the message field + * + * @return all subfields + */ + public String[] getSubFields() { + return subFields; + } + + /** + * Sets all subfields of the message field + * + * @param subFields All new subfields + */ + public void setSubFields(String[] subFields) { + this.subFields = subFields; + } + + /** + * Gets the emote next to the message field + * + * @return the emote of the field + */ + public FieldEmote getEmote() { + return emote; + } + + /** + * Sets the emote next to the field + * + * @param emote The new field emote + */ + public void setEmote(FieldEmote emote) { + this.emote = emote; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageType.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageType.java new file mode 100644 index 0000000..01a90f0 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/MessageType.java @@ -0,0 +1,34 @@ +package xyz.sheepstar.util.bot.builder.message; + +import java.awt.*; + +public enum MessageType { + + ERROR(new Color(0xde1f1f)), + PRIMARY(new Color(0x748AD6)), + SUCCESS(new Color(0x2ecc71)), + WARNING(new Color(0xFF8C00)), + SECONDARY(new Color(0x4E4C4C)), + WHITE(new Color(0xE9E3E3)), + BLACK(new Color(0x222222)); + + private final Color color; + + /** + * Constructor of the {@link MessageType} enum + * + * @param color The color of the message + */ + MessageType(Color color) { + this.color = color; + } + + /** + * Gets the color of the message type + * + * @return the color as {@link Color} + */ + public Color getColor() { + return color; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/Translate.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/Translate.java new file mode 100644 index 0000000..bd86853 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/builder/message/Translate.java @@ -0,0 +1,25 @@ +package xyz.sheepstar.util.bot.builder.message; + +public enum Translate { + + /** + * Only translates the title of the message + */ + ONLY_TITLE, + + /** + * Only translates the description of the message + */ + ONLY_DESCRIPTION, + + /** + * Translates the title & the description + */ + BOTH, + + /** + * Translates nothing, neither the title nor the description + */ + NOTHING + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/Arguments.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/Arguments.java new file mode 100644 index 0000000..2b7dc52 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/Arguments.java @@ -0,0 +1,116 @@ +package xyz.sheepstar.util.bot.command; + +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.GuildChannel; +import net.dv8tion.jda.api.entities.Role; +import net.dv8tion.jda.api.entities.User; +import xyz.sheepstar.core.SheepstarCore; + +import java.util.HashMap; + +public class Arguments { + + private final HashMap<String, String> argumentList; + + private final JDA jda = SheepstarCore.getSheepstar().getJDA(); + + /** + * Basic constructor of the {@link Arguments} (the argument list of the {@link GuildCommand}) + * + * @param argumentList The list of arguments you want to add to the command + */ + public Arguments(HashMap<String, String> argumentList) { + this.argumentList = argumentList; + } + + /** + * Gets a string from the argument list + * + * @param key The key of the string you want to get + * @return the string from the argument list + */ + public String getString(String key) { + return argumentList.get(key.toLowerCase()); + } + + /** + * Gets an integer from the argument list + * + * @param key The key of the integer you want to get + * @return the integer from the argument list + */ + public int getInteger(String key) { + return Integer.parseInt(argumentList.get(key.toLowerCase())); + } + + /** + * Gets a boolean from the argument list + * + * @param key The key of the boolean you want to get + * @return the boolean from the argument list + */ + public boolean getBoolean(String key) { + return Boolean.parseBoolean(argumentList.get(key.toLowerCase())); + } + + /** + * Retrieves a user from the argument list + * + * @param key The key of the user you want to get + * @return the user from the argument list + */ + public User retrieveUser(String key) { + return jda.retrieveUserById(argumentList.get(key.toLowerCase())).complete(); + } + + /** + * Gets a user from the argument list + * + * @param key The key of the user you want to get + * @return the user from the argument list + */ + public User getUser(String key) { + return jda.getUserById(argumentList.get(key.toLowerCase())); + } + + /** + * Gets a channel from the argument list + * + * @param key The key of the channel you want to get + * @return the channel from the argument list + */ + public GuildChannel getChannel(String key) { + return jda.getGuildChannelById(argumentList.get(key.toLowerCase())); + } + + /** + * Gets a role from the argument list + * + * @param key The key of the role you want to get + * @return the role from the argument list + */ + public Role getRole(String key) { + return jda.getRoleById(argumentList.get(key.toLowerCase())); + } + + /** + * Checks if the provided key exists in the argument list + * + * @param key The key you want to check + * @return <code>true</code> if the key exists, otherwise <code>false</code> + */ + public boolean exists(String key) { + return argumentList.containsKey(key.toLowerCase()) && argumentList.get(key.toLowerCase()) != null + && !argumentList.get(key.toLowerCase()).isEmpty(); + } + + /** + * Gets the full list of arguments + * + * @return the full list of arguments + */ + public HashMap<String, String> getArgumentList() { + return argumentList; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/CommandRunnable.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/CommandRunnable.java new file mode 100644 index 0000000..bebabd8 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/CommandRunnable.java @@ -0,0 +1,7 @@ +package xyz.sheepstar.util.bot.command; + +public interface CommandRunnable { + + void run() throws Exception; + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildCommand.java new file mode 100644 index 0000000..b892f5d --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildCommand.java @@ -0,0 +1,367 @@ +package xyz.sheepstar.util.bot.command; + +import net.dv8tion.jda.api.Permission; +import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; +import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; +import net.dv8tion.jda.api.interactions.components.ButtonStyle; +import org.jetbrains.annotations.NotNull; +import xyz.sheepstar.util.bot.builder.message.MessageType; +import xyz.sheepstar.util.bot.builder.message.Translate; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.listener.ListenerBasics; +import xyz.sheepstar.util.bot.manager.sql.SettingsManager; +import xyz.sheepstar.util.bot.permission.PermissionNode; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public abstract class GuildCommand extends ListenerBasics { + + protected final CommandMeta commandMeta = this.getClass().getAnnotation(CommandMeta.class); + private final ArrayList<OptionData> syntaxElements = new ArrayList<>(); + private final SettingsManager settingsManager = api.getBotManager().getSettingsManager(); + protected ArrayList<String> subAliases = new ArrayList<>(); + protected ArrayList<String> aliases = new ArrayList<>(); + + /** + * The basic constructor of the {@link GuildCommand} + */ + public GuildCommand() { + addAliases(); + usage(); + } + + /** + * Gets the full message in parts (splits with spaces and quotation marks) + * + * @param input The message input + * @return the full message in parts + */ + public static ArrayList<String> getPartsFromInput(String input) { + Matcher argumentMatcher = Pattern.compile("([^\"]\\S*|\".+?\")\\s*").matcher(input); + + ArrayList<String> arguments = new ArrayList<>(); + + while (argumentMatcher.find()) { + arguments.add(argumentMatcher.group(1)); + } + + return arguments; + } + + /** + * Adds all sub-aliases and aliases + */ + protected void addAliases() { + Collections.addAll(aliases, commandMeta.aliases()); + Collections.addAll(subAliases, commandMeta.subAliases()); + } + + public void usage() { + + } + + public abstract void execute(GuildEventController event, Arguments args) throws Exception; + + /** + * The override of the {@link SlashCommandEvent}. Used to run the execute-method + * + * @param event The {@link SlashCommandEvent} from the JDA + */ + @Override + public void onSlashCommand(@NotNull SlashCommandEvent event) { + api.getScheduledExecutorPool().executeInstant("SR-PreparePool", () -> { + if (!event.getChannelType().isGuild()) return; + + if (event.getUser().isBot()) return; + + if (!api.getConfig().getCommandConfiguration().isSlashEnabled()) return; + + if (!aliases.contains(event.getName())) return; + + if (commandMeta.subAliases().length != 0) { + if (!subAliases.contains(event.getSubcommandName())) return; + } + + GuildEventController controller = new GuildEventController(event.getUser(), event.getMember(), event.getTextChannel(), event.getGuild(), this.getClass()) + .useEvent(event); + + if (!isEnabled(event.getGuild())) { + controller.custom(MessageType.ERROR, "bot.error", "bot.module.not_enabled", Translate.BOTH) + .addButton(ButtonStyle.SUCCESS, "enable", translate("bot.enable_module", event.getGuild())) + .send(); + return; + } + + HashMap<String, String> argumentMap = new HashMap<>(); + event.getOptions().forEach(option -> argumentMap.put(option.getName(), option.getAsString())); + + api.getScheduledExecutorPool().executeInstant("SR-CommandPool", () -> + runSecure(controller, () -> prepareExecute(controller, new Arguments(argumentMap)))); + }); + } + + /** + * The override of the {@link GuildMessageReceivedEvent}. Used to run the execute-method + * + * @param event The {@link GuildMessageReceivedEvent} from the JDA + */ + @Override + public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { + api.getScheduledExecutorPool().executeInstant("SR-PreparePool", () -> { + if (event.getMessage().getAuthor().isBot()) return; + + String prefix = getPrefix(event.getGuild()); + + String messageInput = event.getMessage().getContentRaw() + .replaceAll("<@!?(\\d+)>", "$1") + .replaceAll("<@&(\\d+)>", "$1") + .replaceAll("<#(\\d+)>", "$1") + .replaceAll("\"", ""); + + if (!isEnabled(event.getGuild())) return; + + ArrayList<String> parts = getPartsFromInput(messageInput); + + if (!parts.get(0).startsWith(jda.getSelfUser().getId())) { + + if (!api.getConfig().getCommandConfiguration().isPrefixEnabled()) return; + + if (!event.getMessage().getContentRaw().startsWith(prefix)) return; + + if (!aliases.contains(parts.get(0).substring(prefix.length()).toLowerCase())) return; + + if (commandMeta.subAliases().length != 0 && !subAliases.contains(parts.get(1))) return; + } else { + if (!api.getConfig().getCommandConfiguration().isPingEnabled()) return; + + if (!aliases.contains(parts.get(1))) return; + + if (commandMeta.subAliases().length != 0 && !subAliases.contains(parts.get(2))) return; + } + + GuildEventController controller = new GuildEventController(event.getAuthor(), event.getMember(), event.getChannel(), event.getGuild(), this.getClass()) + .useEvent(event); + + api.getScheduledExecutorPool().executeInstant("SR-CommandPool", () -> + runSecure(controller, () -> prepareExecute(controller, getArgumentsFromInput(parts)))); + }); + } + + /** + * Gets the arguments from the input + * + * @param arguments The arguments you got from your message + * @return the arguments from the input + */ + public Arguments getArgumentsFromInput(ArrayList<String> arguments) throws PublicCommandException { + if (arguments.get(0).equals(jda.getSelfUser().getId())) arguments.remove(0); + + arguments.remove(0); + + if (commandMeta.subAliases().length != 0) arguments.remove(0); + + HashMap<String, String> syntaxMap = new HashMap<>(); + + for (int i = 0; i < getSyntaxElements().size(); i++) { + + OptionData syntaxElement = syntaxElements.get(i); + boolean argumentProvided = arguments.size() > i; + + if (syntaxElement.isRequired() && !argumentProvided) { + throw new PublicCommandException("bot.wrong_syntax", parseSyntaxAsString()); + } + + if (argumentProvided && !isValidArgument(syntaxElement.getType(), arguments.get(i))) { + throw new PublicCommandException("bot.wrong_type", syntaxElement.getName(), syntaxElement.getType().toString()); + } + + syntaxMap.put(syntaxElement.getName(), argumentProvided ? arguments.get(i) : null); + } + + return new Arguments(syntaxMap); + } + + /** + * Gets the usage of the command as a string + * + * @return the usage of the command as a string + */ + public String parseSyntaxAsString() { + StringBuilder syntax = new StringBuilder(); + for (OptionData syntaxElement : getSyntaxElements()) { + String format = syntaxElement.isRequired() ? "<%s>" : "[%s]"; + + if (!syntax.toString().isEmpty()) syntax.append(" "); + + syntax.append(String.format(format, syntaxElement.getName())); + } + return syntax.toString(); + } + + /** + * Checks if the provided argument equals the provided type + * + * @param expectedType The type you want to check + * @param givenArgument The argument you want to check + * @return <code>true</code> if the argument matches the expected type, otherwise <code>false</code> + */ + public boolean isValidArgument(OptionType expectedType, String givenArgument) { + try { + if (expectedType == OptionType.INTEGER) + Integer.parseInt(givenArgument); + + if (expectedType == OptionType.BOOLEAN && !(givenArgument.equals("false") || givenArgument.equals("true"))) + throw new Exception(); + + if (expectedType == OptionType.USER && jda.retrieveUserById(givenArgument).complete() == null) + throw new Exception(); + + if (expectedType == OptionType.CHANNEL && jda.getGuildChannelById(givenArgument) == null) + throw new Exception(); + + if (expectedType == OptionType.ROLE && jda.getRoleById(givenArgument) == null) + throw new Exception(); + } catch (Exception e) { + return false; + } + + return true; + } + + /** + * Prepares the execution of the command event + * + * @param event The {@link GuildEventController} from the events + * @param arguments The arguments from the message/event + */ + protected void prepareExecute(GuildEventController event, Arguments arguments) throws Exception { + + // Check if the user has the permission to execute the command + if (!isAuthorized(event)) + throw new PublicCommandException("bot.lacking_permission", commandMeta.permission().name()); + + // Checks if the required setting is set + if (!commandMeta.requiredSetting().isEmpty() + && !settingsManager.getSetting(event.getGuild(), getModule(), commandMeta.requiredSetting()).equals(commandMeta.requiredSettingValue())) + throw new PublicCommandException("bot.invalid_setting", commandMeta.requiredSetting(), commandMeta.requiredSettingValue()); + + execute(event, arguments); + } + + /** + * Checks if the user is allowed to run the command + * + * @param event The {@link GuildEventController} + * @return <code>true</code> if the user is authorized, otherwise <code>false</code> + */ + public boolean isAuthorized(GuildEventController event) { + if (commandMeta.permission() == null || commandMeta.permission() == PermissionNode.DEFAULT) return true; + + if (commandMeta.permission() == PermissionNode.ADMINISTRATOR) + return event.getMember().hasPermission(Permission.ADMINISTRATOR); + + if (commandMeta.permission() == PermissionNode.SERVER_OWNER) + return event.getMember().isOwner(); + + if (commandMeta.permission() == PermissionNode.BOT_OWNER) + if (api.isOwner(event.getAuthor())) return true; + + if (commandMeta.permission() == PermissionNode.SUPPORTER) + return api.isSupporter(event.getAuthor()); + + return false; + } + + @Override + public void onButtonClick(@NotNull ButtonClickEvent event) { + GuildEventController controller = new GuildEventController(event.getUser(), event.getMember(), event.getTextChannel(), event.getGuild(), this.getClass()) + .useEvent(event); + + runSecure(controller, () -> { + if (!event.getMessage().getAuthor().getId().equals(jda.getSelfUser().getId())) return; + + String[] buttonMeta = event.getComponentId().split("~"); + + if (!buttonMeta[0].equals(getClass().getName())) return; + + if (buttonMeta[1].equals("enable") && event.getMember().hasPermission(Permission.ADMINISTRATOR)) { + String moduleId = getModuleByClass(getClass()); + if (api.getModuleManager().getActivated_modules().containsKey(moduleId)) + moduleManager.enableModule(event.getGuild(), moduleId, "!"); + controller.success("bot.module_enabled", moduleId, "!"); + return; + } + + if (!isEnabled(event.getGuild())) return; + + if (!isAuthorized(controller)) return; + + buttonClick(controller, buttonMeta[1]); + }); + } + + public void buttonClick(GuildEventController event, String id) throws Exception { + + } + + /** + * The default method to get the {@link SyntaxBuilder} + * + * @param type The option type of the syntax element + * @param name The name of the syntax element + * @param description The description of the syntax element + * @param isRequired <code>true</code> if the syntax element is required, otherwise <code>false</code> + * @return the {@link SyntaxBuilder} + */ + public SyntaxBuilder usage(OptionType type, String name, String description, boolean isRequired) { + return new SyntaxBuilder(this, type, name, description).required(isRequired); + } + + /** + * Gets the {@link SyntaxBuilder} + * + * @param type The option of the syntax element + * @param name The name of the syntax element + * @param description The description of the syntax element + * @return the {@link SyntaxBuilder} + */ + public SyntaxBuilder usage(OptionType type, String name, String description) { + return new SyntaxBuilder(this, type, name, description); + } + + /** + * Gets the {@link SyntaxBuilder} + * + * @param name The name of the syntax element + * @param description The description of the syntax element + * @return the created {@link SyntaxBuilder} with prefilled values + */ + public SyntaxBuilder usage(String name, String description) { + return new SyntaxBuilder(this, OptionType.STRING, name, description); + } + + /** + * Adds a syntax element ({@link OptionData}) to the syntax element list + * + * @param optionData The {@link OptionData} generated by the {@link SyntaxBuilder} + */ + public void addSyntaxElement(OptionData optionData) { + syntaxElements.add(optionData); + } + + /** + * Gets the list of syntax elements + * + * @return the list of syntax elements + */ + public ArrayList<OptionData> getSyntaxElements() { + return syntaxElements; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildEventController.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildEventController.java new file mode 100644 index 0000000..a12e7f9 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/GuildEventController.java @@ -0,0 +1,395 @@ +package xyz.sheepstar.util.bot.command; + +import net.dv8tion.jda.api.MessageBuilder; +import net.dv8tion.jda.api.entities.*; +import net.dv8tion.jda.api.events.Event; +import net.dv8tion.jda.api.events.interaction.ButtonClickEvent; +import net.dv8tion.jda.api.events.interaction.SlashCommandEvent; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import net.dv8tion.jda.api.interactions.InteractionHook; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.bot.builder.message.DefaultResponseBuilder; +import xyz.sheepstar.util.bot.builder.message.MessageField; +import xyz.sheepstar.util.bot.builder.message.MessageType; +import xyz.sheepstar.util.bot.builder.message.Translate; + +import java.util.ArrayList; + +public class GuildEventController { + + private final SheepstarImpl api = SheepstarCore.getSheepstar(); + + private final User author; + private final Member member; + private final TextChannel channel; + private final Guild guild; + + private final Class<?> trigger; + + private String translationLanguage; + + private InteractionHook interactionHook; + private Event event; + + /** + * Basic constructor of the {@link GuildEventController} + * + * @param author The author that triggered command event + * @param member The member that triggered the command event + * @param channel The channel of the triggered command event + * @param guild The guild of the triggered command event + * @param trigger The trigger of the command event + */ + public GuildEventController(User author, Member member, TextChannel channel, Guild guild, Class<?> trigger) { + this.author = author; + this.member = member; + this.channel = channel; + this.guild = guild; + this.trigger = trigger; + } + + /** + * Waits for the user to send a message + * + * @param ephemeral Should the message be ephemeral? + */ + public void pleaseWait(boolean ephemeral) { + if (event instanceof SlashCommandEvent) + this.interactionHook = ((SlashCommandEvent) event).deferReply(ephemeral).complete(); + } + + /** + * Waits for the user to send a message + */ + public void pleaseWait() { + pleaseWait(false); + } + + + /** + * Tells the event controller to use the defined event. + * <p> + * The current supported events: + * <ol> + * <li>The {@link GuildMessageReceivedEvent}</li> + * <li>The {@link SlashCommandEvent}</li> + * <li>The {@link ButtonClickEvent}</li> + * </ol> + * + * @param event The event from the listener + * @return this class + */ + public GuildEventController useEvent(Event event) { + this.event = event; + return this; + } + + /** + * Gets the author of the command event + * + * @return the author of the command event + */ + public User getAuthor() { + return author; + } + + /** + * Gets the member of the command event + * + * @return the member of the command event + */ + public Member getMember() { + return member; + } + + /** + * Gets the channel of the command event + * + * @return the channel of the command event + */ + public TextChannel getChannel() { + return channel; + } + + /** + * Gets the guild of the command event + * + * @return the guild of the command event + */ + public Guild getGuild() { + return guild; + } + + /** + * Sends an embed message to the specified channel + * + * @param message The embed message you want to send + * @param ephemeral Should only the executor see the message embed? + * Only works for the {@link SlashCommandEvent} + */ + public void reply(MessageEmbed message, boolean ephemeral) { + reply(new MessageBuilder().setEmbeds(message).build(), ephemeral); + } + + /** + * Sends a message to the specified channel + * + * @param message The message you want to send + * @param ephemeral Should only the executor see the message? + * Only works for the {@link SlashCommandEvent} + */ + public void reply(Message message, boolean ephemeral) { + if (interactionHook != null) { + interactionHook.setEphemeral(ephemeral).editOriginal(message).queue(msg -> { + }, thr -> handleReplyError(message)); + } else if (event instanceof GuildMessageReceivedEvent) { + ((GuildMessageReceivedEvent) event).getMessage().reply(message).queue(msg -> { + }, thr -> handleReplyError(message)); + } else if (event instanceof SlashCommandEvent) { + ((SlashCommandEvent) event).reply(message).setEphemeral(ephemeral).queue(msg -> { + }, thr -> handleReplyError(message)); + } else if (event instanceof ButtonClickEvent) { + ((ButtonClickEvent) event).editMessage(message).queue(msg -> { + }, thr -> handleReplyError(message)); + } else { + channel.sendMessage(message).queue(msg -> { + }, thr -> { + }); + } + } + + /** + * Sends a message to the specified channel (on error) + * + * @param msg The message you want to send + */ + private void handleReplyError(Message msg) { + channel.sendMessage(new MessageBuilder(msg).append("\n*:warning: Could not reply to message, sending here*").build()).queue(m -> { + }, thr -> { + }); + } + + /** + * Sends a message to the specified channel + * + * @param message The message you want to send + */ + public void reply(DefaultResponseBuilder message) { + Message build = message.build(); + reply(build, message.isEphemeral()); + } + + /** + * Sends a message to the specified channel + * + * @param message The message you want to send + */ + public void reply(Message message) { + reply(message, false); + } + + /** + * Sends an embed message to the specified channel + * + * @param embed The embed message you want to send + */ + public void reply(MessageEmbed embed) { + reply(embed, true); + } + + /** + * Sends a simple message to the specified channel + * + * @param message The message you want to send + */ + public void reply(String message) { + reply(new MessageBuilder(message).build()); + } + + /** + * Replies a simple success message + * + * @param title The title of the message + * @param description The description of the message + * @param translate Choose which values should be translated (title, description, both, nothing) + * @param parameters Optional translation parameters for the description + */ + public void success(String title, String description, Translate translate, Object... parameters) { + simple(MessageType.SUCCESS, title, description, translate, parameters); + } + + /** + * Replies a simple error message + * + * @param title The title of the message + * @param description The description of the message + * @param translate Choose which values should be translated (title, description, both, nothing) + * @param parameters Optional translation parameters for the description + */ + public void error(String title, String description, Translate translate, Object... parameters) { + simple(MessageType.ERROR, title, description, translate, parameters); + } + + /** + * Replies a simple primary message + * + * @param title The title of the message + * @param description The description of the message + * @param translate Choose which values should be translated (title, description, both, nothing) + * @param parameters Optional translation parameters for the description + */ + public void primary(String title, String description, Translate translate, Object... parameters) { + simple(MessageType.PRIMARY, title, description, translate, parameters); + } + + /** + * Replies a simple warning message + * + * @param title The title of the message + * @param description The description of the message + * @param translate Choose which values should be translated (title, description, both, nothing) + * @param parameters Optional translation parameters for the description + */ + public void warning(String title, String description, Translate translate, Object... parameters) { + simple(MessageType.WARNING, title, description, translate, parameters); + } + + /** + * Replies a simple success message with only the translation string + * <p> + * This automatically adds <b>.title</b> and <b>.description</b> to the translation string + * + * @param translationString The translation string (for example bot.info) + * @param parameters All translation parameters for the description of the message + */ + public void success(String translationString, Object... parameters) { + success(translationString + ".title", translationString + ".description", Translate.BOTH, parameters); + } + + /** + * Replies a simple error message with only the translation string + * <p> + * This automatically adds <b>.title</b> and <b>.description</b> to the translation string + * + * @param translationString The translation string (for example bot.info) + * @param parameters All translation parameters for the description of the message + */ + public void error(String translationString, Object... parameters) { + error("bot.error", translationString, Translate.BOTH, parameters); + } + + /** + * Replies a simple primary message with only the translation string + * <p> + * This automatically adds <b>.title</b> and <b>.description</b> to the translation string + * + * @param translationString The translation string (for example bot.info) + * @param parameters All translation parameters for the description of the message + */ + public void primary(String translationString, Object... parameters) { + primary(translationString + ".title", translationString + ".description", Translate.BOTH, parameters); + } + + /** + * Replies a simple warning message with only the translation string + * <p> + * This automatically adds <b>.title</b> and <b>.description</b> to the translation string + * + * @param translationString The translation string (for example bot.info) + * @param parameters All translation parameters for the description of the message + */ + public void warning(String translationString, Object... parameters) { + warning(translationString + ".title", translationString + ".description", Translate.BOTH, parameters); + } + + /** + * Replies directly from the {@link GuildEventController#custom} method + * + * @param type The type of the message (for example primary or error) + * @param title The title of the message + * @param description The description of the message + * @param translate Choose which values should be translated (title, description, both, nothing) + * @param parameters Optional translation parameters for the description + */ + public void simple(MessageType type, String title, String description, Translate translate, Object... parameters) { + custom(type, title, description, translate, parameters).send(); + } + + /** + * Prepares a custom response builder + * + * @param type The type of the message (for example primary or error) + * @param title The title of the message + * @param description The description of the message + * @param translate Choose which values should be translated (title, description, both, nothing) + * @param parameters Optional translation parameters for the description + * @return the built response builder + */ + public DefaultResponseBuilder custom(MessageType type, String title, String description, Translate translate, Object... parameters) { + return custom(type) + .withTitle((translate == Translate.BOTH || translate == Translate.ONLY_TITLE) ? api.translate(title, getLanguage()) : title) + .withDescription((translate == Translate.BOTH || translate == Translate.ONLY_DESCRIPTION) ? + api.translate(description, getLanguage(), parameters) : String.format(description, parameters)); + } + + /** + * Sends a message with translated title + * + * @param type The type of the message (for example primary or error) + * @param titleTranslation The title translation string + * @param fields The message fields + * @param titleParameters The parameters used for the title + */ + public void custom(MessageType type, String titleTranslation, ArrayList<MessageField> fields, Object... titleParameters) { + try { + custom(type).withTitle(api.translate(titleTranslation, getLanguage(), titleParameters)).withFields(fields).send(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Prepares the {@link DefaultResponseBuilder} with a translated title and description + * <p> + * This automatically adds <b>.title</b> and <b>.description</b> to the translation string + * + * @param type The type of the message (for example primary or error) + * @param translationString The translation string you want to use + * @param parameters The parameters used in the translation + * @return the built {@link DefaultResponseBuilder} + */ + public DefaultResponseBuilder custom(MessageType type, String translationString, Object... parameters) { + return custom(type, translationString + ".title", translationString + ".description", Translate.BOTH, parameters); + } + + /** + * Prepares the {@link DefaultResponseBuilder} so you can edit it completely + * + * @param messageType The type of the message (for example primary or error) + * @return the built {@link DefaultResponseBuilder} with prefilled trigger and color + */ + public DefaultResponseBuilder custom(MessageType messageType) { + return new DefaultResponseBuilder(this, trigger).withColor(messageType); + } + + /** + * Gets the defined event + * + * @return the event + */ + public Event getEvent() { + return event; + } + + /** + * Gets the guild language + * <p> + * Created to not check the guild language in every second + * + * @return the current guild language + */ + public String getLanguage() { + return translationLanguage == null ? api.getBotManager().getGuildManager().getLanguage(guild) : translationLanguage; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/PublicCommandException.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/PublicCommandException.java new file mode 100644 index 0000000..a081a6b --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/PublicCommandException.java @@ -0,0 +1,37 @@ +package xyz.sheepstar.util.bot.command; + +public class PublicCommandException extends Exception { + + private final String translationString; + private final Object[] translationParameters; + + /** + * Basic constructor of the {@link PublicCommandException} + * + * @param translationString The translation string of the message (embed) + * @param translationParameters The optional objects you want to pass in + */ + public PublicCommandException(String translationString, Object... translationParameters) { + this.translationString = translationString; + this.translationParameters = translationParameters; + } + + /** + * Gets the translation string + * + * @return the translation string + */ + public String getTranslationString() { + return translationString; + } + + /** + * Gets the translation parameters + * + * @return the translation parameters + */ + public Object[] getTranslationParameters() { + return translationParameters; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/SyntaxBuilder.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/SyntaxBuilder.java new file mode 100644 index 0000000..9f0d70d --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/SyntaxBuilder.java @@ -0,0 +1,32 @@ +package xyz.sheepstar.util.bot.command; + +import net.dv8tion.jda.api.interactions.commands.OptionType; +import net.dv8tion.jda.api.interactions.commands.build.OptionData; + +public class SyntaxBuilder { + + private final GuildCommand command; + + private final OptionData syntaxElement; + + public SyntaxBuilder(GuildCommand command, OptionType type, String name, String description) { + this.command = command; + syntaxElement = new OptionData(type, name.toLowerCase(), description); + } + + public SyntaxBuilder required(boolean required) { + syntaxElement.setRequired(required); + return this; + } + + public SyntaxBuilder addChoice(String name, String value) { + syntaxElement.addChoice(name, value); + return this; + } + + public void add() { + command.addSyntaxElement(syntaxElement); + } + + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/annotations/CommandMeta.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/annotations/CommandMeta.java new file mode 100644 index 0000000..e8c71a8 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/annotations/CommandMeta.java @@ -0,0 +1,23 @@ +package xyz.sheepstar.util.bot.command.annotations; + +import xyz.sheepstar.util.bot.permission.PermissionNode; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface CommandMeta { + + String[] aliases(); + + String[] subAliases() default {}; + + PermissionNode permission() default PermissionNode.DEFAULT; + + String description(); + + String requiredSetting() default ""; + + String requiredSettingValue() default "yes"; + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/general/GeneralGuildCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/general/GeneralGuildCommand.java new file mode 100644 index 0000000..fa61ac4 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/command/general/GeneralGuildCommand.java @@ -0,0 +1,92 @@ +package xyz.sheepstar.util.bot.command.general; + +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import org.jetbrains.annotations.NotNull; +import xyz.sheepstar.util.bot.command.Arguments; +import xyz.sheepstar.util.bot.command.GuildCommand; +import xyz.sheepstar.util.bot.command.GuildEventController; + +import java.util.ArrayList; +import java.util.HashMap; + +public abstract class GeneralGuildCommand extends GuildCommand { + + @Override + public void execute(GuildEventController event, Arguments args) throws Exception { + execute(event, args, args.getString("modulename")); + } + + @Override + public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { + api.getScheduledExecutorPool().executeInstant("SR-PreparePool", () -> { + if (event.getMessage().getAuthor().isBot()) return; + + String messageInput = event.getMessage().getContentRaw() + .replaceAll("<@!?(\\d+)>", "$1") + .replaceAll("<@&(\\d+)>", "$1") + .replaceAll("<#(\\d+)>", "$1") + .replaceAll("\"", ""); + + GuildEventController controller = new GuildEventController(event.getAuthor(), event.getMember(), event.getChannel(), event.getGuild(), this.getClass()) + .useEvent(event); + + ArrayList<String> parts = getPartsFromInput(messageInput); + + if (!parts.get(0).startsWith(jda.getSelfUser().getId())) { + if (!api.getConfig().getCommandConfiguration().isPrefixEnabled()) return; + + String module = getModuleNameByInput(event.getGuild(), event.getMessage().getContentRaw()); + + parts.add(module); + + String modulePrefix = moduleManager.getPrefix(event.getGuild(), module); + + if (!event.getMessage().getContentRaw().startsWith(modulePrefix)) return; + + if (!aliases.contains(parts.get(0).substring(modulePrefix.length()).toLowerCase())) return; + + if (commandMeta.subAliases().length != 0 && !subAliases.contains(parts.get(1))) return; + } else { + if (!api.getConfig().getCommandConfiguration().isPingEnabled()) return; + + if (!aliases.contains(parts.get(1))) return; + + if (commandMeta.subAliases().length != 0 && !subAliases.contains(parts.get(2))) return; + } + + api.getScheduledExecutorPool().executeInstant("SR-CommandPool", () -> runSecure(controller, () -> + prepareExecute(controller, getArgumentsFromInput(parts)))); + }); + } + + public void generalUsage() { + } + + public abstract void execute(GuildEventController event, Arguments args, String moduleName) throws Exception; + + @Override + public boolean isEnabled(Guild guild) { + return true; + } + + @Override + public void usage() { + usage("modulename", "The name of the module you want to use").required(true).add(); + generalUsage(); + } + + /** + * Gets a module by the message input + * + * @param guild The guild you want to use + * @param input The input you want to get the module from + * @return the name of the module + */ + public String getModuleNameByInput(Guild guild, String input) { + for (HashMap<String, Object> module : moduleManager.getModules(guild)) + if (input.startsWith((String) module.get("prefix"))) return (String) module.get("moduleID"); + + return null; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/emote/INTERN_EMOTE.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/emote/INTERN_EMOTE.java new file mode 100644 index 0000000..5762191 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/emote/INTERN_EMOTE.java @@ -0,0 +1,35 @@ +package xyz.sheepstar.util.bot.emote; + +public enum INTERN_EMOTE { + + INFO(888142370904883250L), + NEW(888142370846146580L), + NITRO(888142372465168394L), + UNDERAGE(858746101581742130L), + ARROW_RIGHT(888142370808422440L), + ARROW_LEFT(888142370770649109L), + CHECK(888142371487903754L), + STAR_COIN(911717404990668830L), + ERROR(888142370535796837L); + + private final long emoteID; + + /** + * Basic constructor of the {@link INTERN_EMOTE} + * + * @param emoteID The id of the emote + */ + INTERN_EMOTE(long emoteID) { + this.emoteID = emoteID; + } + + /** + * Gets the ID of the emote + * + * @return the id of the emote + */ + public long getID() { + return emoteID; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/GuildListener.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/GuildListener.java new file mode 100644 index 0000000..2c83326 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/GuildListener.java @@ -0,0 +1,24 @@ +package xyz.sheepstar.util.bot.listener; + + +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; +import org.jetbrains.annotations.NotNull; +import xyz.sheepstar.util.bot.command.GuildEventController; + +public abstract class GuildListener extends ListenerBasics { + + @Override + public void onGuildMessageReceived(@NotNull GuildMessageReceivedEvent event) { + GuildEventController controller = new GuildEventController(event.getAuthor(), event.getMember(), event.getChannel(), event.getGuild(), this.getClass()) + .useEvent(event); + + api.getScheduledExecutorPool().executeInstant("SR-ListenerPool", () -> runSecure(controller, () -> + messageReceived(controller, event.getMessage()))); + } + + public void messageReceived(GuildEventController event, Message message) throws Exception { + + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerBasics.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerBasics.java new file mode 100644 index 0000000..f5602e7 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerBasics.java @@ -0,0 +1,298 @@ +package xyz.sheepstar.util.bot.listener; + +import de.gnmyt.sqltoolkit.storage.SQLTable; +import net.dv8tion.jda.api.JDA; +import net.dv8tion.jda.api.entities.Emote; +import net.dv8tion.jda.api.entities.Guild; +import net.dv8tion.jda.api.exceptions.ErrorResponseException; +import net.dv8tion.jda.api.exceptions.HierarchyException; +import net.dv8tion.jda.api.exceptions.InsufficientPermissionException; +import net.dv8tion.jda.api.hooks.ListenerAdapter; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.bot.command.CommandRunnable; +import xyz.sheepstar.util.bot.command.GuildEventController; +import xyz.sheepstar.util.bot.command.PublicCommandException; +import xyz.sheepstar.util.bot.emote.INTERN_EMOTE; +import xyz.sheepstar.util.bot.manager.sql.ModuleManager; +import xyz.sheepstar.util.mapper.JSONContent; +import xyz.sheepstar.util.sql.SheepDatabase; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ListenerBasics extends ListenerAdapter { + + public JDA jda = SheepstarCore.getSheepstar().getJDA(); + public SheepstarImpl api = SheepstarCore.getSheepstar(); + protected ModuleManager moduleManager = api.getBotManager().getModuleManager(); + + /** + * Gets a module by its class + * + * @param className The classname as a string + * @return the name of the module + */ + public String getModuleByClass(String className) { + return api.getModuleName(className); + } + + /** + * Gets a module by its class + * + * @param clazz The class under which the module is registered + * @return the name of the module + */ + public String getModuleByClass(Class<? extends ListenerAdapter> clazz) { + return api.getModuleName(clazz.getName()); + } + + /** + * Gets the module name of the superclass + * + * @return the name of the module + */ + public String getModule() { + return api.getModuleName(super.getClass().getName()); + } + + /** + * Translates a translationString to the provided language + * + * @param translationString The string you want to translate + * @param languageCode The language you want to translate the string to + * @param variables The optional variables you need to pass to the string + * @return the translated message + */ + public String translate(String translationString, String languageCode, Object... variables) { + return api.translate(translationString, languageCode, variables); + } + + /** + * Translates a translationString to the provided language + * + * @param translationString The string you want to translate + * @param guild The guild you want to get the language from + * @param variables The optional variables you need to pass to the string + * @return the translated message + */ + public String translate(String translationString, Guild guild, Object... variables) { + return translate(translationString, getLanguage(guild), variables); + } + + /** + * Gets the language of an guild + * + * @param guild The guild you want to get the language from + * @return The language in a lower case + */ + public String getLanguage(Guild guild) { + return api.getBotManager().getGuildManager().getLanguage(guild); + } + + /** + * Gets the prefix of the module from the superclass + * + * @param guild The guild you want to the the prefix from + * @return the module prefix + */ + public String getPrefix(Guild guild) { + return api.getBotManager().getModuleManager().getPrefix(guild, getModuleByClass(super.getClass())); + } + + /** + * Runs a runnable without printing the stacktrace if an error happens + * + * @param run The runnable you want to run + */ + public void runIgnored(Runnable run) { + try { + run.run(); + } catch (Exception ignored) { + } + } + + + /** + * Runs a {@link CommandRunnable} in a secure try-catch block to inform the user about errors + * + * @param controller The {@link GuildEventController} from the events + * @param runnable The action you want to run + */ + public void runSecure(GuildEventController controller, CommandRunnable runnable) { + try { + runnable.run(); + } catch (PublicCommandException e) { + controller.error(e.getTranslationString(), e.getTranslationParameters()); + } catch (InsufficientPermissionException e) { + controller.error("bot.insufficient_permission", e.getPermission().getName()); + } catch (HierarchyException e) { + controller.error("bot.hierarchy_error"); + } catch (ErrorResponseException e) { + controller.error("bot.response_error", e.getMeaning(), e.getErrorCode()); + } catch (Exception e) { + if (api.isDebugModeEnabled()) e.printStackTrace(); + controller.error("bot.unexpected_error", "GuildMessageReceivedError", e.getMessage(), + e.getStackTrace()[0].getClassName() + "#" + e.getStackTrace()[0].getLineNumber()); + } + } + + /** + * Runs a runnable asynchronously + * + * @param run The runnable you want to run + */ + public void runAsync(Runnable run) { + CompletableFuture.runAsync(run); + } + + /** + * Runs a runnable ignored and asynchronously + * + * @param run The runnable you want to run + */ + public void runAsyncIgnored(Runnable run) { + runAsync(() -> runIgnored(run)); + } + + /** + * Gets an emote mention by name + * + * @param emoteName The name of the emote + * @return the emote mention + */ + public String getEmoteStringByName(String emoteName) { + return getEmoteByName(emoteName, false).getAsMention(); + } + + /** + * Gets a emote mention by id + * + * @param emoteID The id of the emote + * @return the emote mention + */ + public String getEmoteStringById(String emoteID) { + return getEmoteById(emoteID).getAsMention(); + } + + /** + * Gets an emote string by the {@link INTERN_EMOTE} enum + * + * @param emote The emote you want to get + * @return the emote as a string + */ + public String getEmoteString(INTERN_EMOTE emote) { + return getEmoteStringById(String.valueOf(emote.getID())); + } + + /** + * Gets an emote by a name + * + * @param emoteName The name of the emote + * @param ignoreCase Search with ignoring the case? + * @return the emote + */ + public Emote getEmoteByName(String emoteName, boolean ignoreCase) { + try { + return jda.getEmotesByName(emoteName, ignoreCase).get(0); + } catch (Exception err) { + return getEmoteById("813810764405407814"); + } + } + + /** + * Gets an emote by id + * + * @param emoteID The id of the emote + * @return the emote + */ + public Emote getEmoteById(String emoteID) { + try { + return jda.getEmoteById(emoteID); + } catch (Exception err) { + return jda.getEmoteById(813810764405407814L); + } + } + + /** + * Gets an emote by the {@link INTERN_EMOTE} enum + * + * @param emote The emote you want to get + * @return the emote as an emote object + */ + public Emote getEmote(INTERN_EMOTE emote) { + return getEmoteById(String.valueOf(emote.getID())); + } + + /** + * Checks if the module from the superclass is enabled + * + * @param guild The guild you want to check + * @return a boolean that says if the module is enabled + */ + public boolean isEnabled(Guild guild) { + return moduleManager.isEnabled(guild, getModuleByClass(super.getClass())); + } + + /** + * Shortcut for getting the database + * + * @return the database + */ + public SheepDatabase database() { + return api.getDatabase(); + } + + /** + * Shortcut for getting a SheepTable + * + * @param table The table you want to get + * @return the table + */ + public SQLTable table(Class<? extends SQLTable> table) { + return database().getTableFactory().getTable(table); + } + + /** + * Parses a json string into a json content instance + * + * @param content The json content you want to parse + * @return A new instance of the json content + */ + public JSONContent parseJSON(String content) { + return new JSONContent(content); + } + + /** + * Gets the time/date by a string + * + * @param text The text you want to parse + * Example: 21d5h2m + * @return the string as a {@link Date} + */ + public Date getTimeFromString(String text) { + Matcher m = Pattern.compile("[1-9]+[a-z]").matcher(text); + List<String> list = new ArrayList<>(); + + while (m.find()) list.add(m.group()); + + Calendar calendar = Calendar.getInstance(); + + list.forEach(pattern -> { + if (pattern.endsWith("d")) + calendar.add(Calendar.DATE, Integer.parseInt(pattern.replace("d", ""))); + else if (pattern.endsWith("h")) + calendar.add(Calendar.HOUR, Integer.parseInt(pattern.replace("h", ""))); + else if (pattern.endsWith("m")) + calendar.add(Calendar.MINUTE, Integer.parseInt(pattern.replace("m", ""))); + }); + + return calendar.getTime(); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerInfo.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerInfo.java new file mode 100644 index 0000000..60da507 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/listener/ListenerInfo.java @@ -0,0 +1,47 @@ +package xyz.sheepstar.util.bot.listener; + +public class ListenerInfo { + + private String moduleName; + private Object listener; + + /** + * Gets the listener you set + * + * @return The listener + */ + public Object getListener() { + return listener; + } + + /** + * Sets the listener object + * + * @param listener The new listener object + * @return this class + */ + public ListenerInfo setListener(Object listener) { + this.listener = listener; + return this; + } + + /** + * Gets the name of the module + * + * @return The name of the module + */ + public String getModuleName() { + return moduleName; + } + + /** + * Sets the name of the module + * + * @param moduleName The new name of the module + * @return this class + */ + public ListenerInfo setModuleName(String moduleName) { + this.moduleName = moduleName; + return this; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/BotManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/BotManager.java new file mode 100644 index 0000000..185fb88 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/BotManager.java @@ -0,0 +1,111 @@ +package xyz.sheepstar.util.bot.manager; + +import de.gnmyt.sqltoolkit.factory.TableFactory; +import net.dv8tion.jda.api.entities.Activity; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.bot.manager.sql.*; +import xyz.sheepstar.util.bot.updater.StatusUpdater; + +public class BotManager { + + private final TableFactory tableFactory; + private final SheepstarImpl api; + private StatusUpdater statusUpdater; + + /** + * Loads an creates all managers + * + * @param api The sheepstar instance + */ + public BotManager(SheepstarImpl api) { + this.tableFactory = api.getDatabase().getTableFactory(); + this.api = api; + + // Register sql managers + tableFactory + .register(new GuildManager()) + .register(new TranslationManager()) + .register(new ModuleManager()) + .register(new LanguageManager()) + .register(new SettingsInfoManager()) + .register(new SettingsManager()) + .register(new CommandMetaManager()); + + initAutoUpdater(); + } + + /** + * Initialises the auto status updater + */ + private void initAutoUpdater() { + statusUpdater = new StatusUpdater(api); + + api.getConfig().getActivities().forEach(action -> + statusUpdater.addActivity(Activity.of(action.getType(), action.getName()))); + + statusUpdater.start(); + } + + /** + * Gets the auto updater + * + * @return the status updater + */ + public StatusUpdater getAutoUpdater() { + return statusUpdater; + } + + /** + * Gets the guild manager + * + * @return the guild manager + */ + public GuildManager getGuildManager() { + return (GuildManager) tableFactory.getTable(GuildManager.class); + } + + /** + * Gets the translation manager + * + * @return the translation manager + */ + public TranslationManager getTranslationManager() { + return (TranslationManager) tableFactory.getTable(TranslationManager.class); + } + + /** + * Gets the module manager + * + * @return the module manager + */ + public ModuleManager getModuleManager() { + return (ModuleManager) tableFactory.getTable(ModuleManager.class); + } + + /** + * Gets the language manager + * + * @return the language manager + */ + public LanguageManager getLanguageManager() { + return (LanguageManager) tableFactory.getTable(LanguageManager.class); + } + + /** + * Gets the settings info manager + * + * @return the settings info manager + */ + public SettingsInfoManager getSettingsInfoManager() { + return (SettingsInfoManager) tableFactory.getTable(SettingsInfoManager.class); + } + + /** + * Gets the settings manager + * + * @return the settings manager + */ + public SettingsManager getSettingsManager() { + return (SettingsManager) tableFactory.getTable(SettingsManager.class); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/ImportManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/ImportManager.java new file mode 100644 index 0000000..ea90d09 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/ImportManager.java @@ -0,0 +1,60 @@ +package xyz.sheepstar.util.bot.manager; + +import xyz.sheepstar.util.Sheepstar; +import xyz.sheepstar.util.bot.command.GuildCommand; + +public class ImportManager { + + private final Sheepstar api; + private final String moduleName; + + /** + * Basic constructor for the ImportManager + * + * @param api The sheepstar api + * @param moduleName The name of the module + */ + public ImportManager(Sheepstar api, String moduleName) { + this.api = api; + this.moduleName = moduleName; + } + + /** + * Registers a Listener + * + * @param listener The Listener you want to register + */ + public void registerListener(Object listener) { + api.registerListener(moduleName, listener); + } + + /** + * Registers a command + * + * @param command The command you want to register + */ + public void registerCommand(GuildCommand command) { + api.registerCommand(moduleName, command); + } + + /** + * Registers multiple listeners + * + * @param listeners The listener you want to register + */ + public void registerListeners(Object... listeners) { + for (Object current : listeners) + registerListener(current); + } + + /** + * Registers multiple commands + * + * @param commands The commands you want to register + */ + public void registerCommands(GuildCommand... commands) { + for (GuildCommand command : commands) + registerCommand(command); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/CommandMetaManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/CommandMetaManager.java new file mode 100644 index 0000000..fdb28c3 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/CommandMetaManager.java @@ -0,0 +1,68 @@ +package xyz.sheepstar.util.bot.manager.sql; + +import xyz.sheepstar.util.sql.SheepManager; + +public class CommandMetaManager extends SheepManager { + + @Override + protected String tableName() { + return "command_meta"; + } + + @Override + protected void tableFields() { + custom("module").add(); + custom("name").add(); + custom("sub").allowNull(true).add(); + custom("description").add(); + } + + /** + * Adds a command to the dataset + * + * @param moduleName The name of the module from the command + * @param commandName The name of the command + * @param subAlias The sub alias of the command + * @param description The description of the command + */ + public void addCommand(String moduleName, String commandName, String subAlias, String description) { + insert().value("module", moduleName).value("name", commandName).value("sub", subAlias).value("description", description).execute(); + } + + /** + * Adds a command to the dataset + * + * @param moduleName The name of the module from the command + * @param commandName The name of the command + * @param description The description of the command + */ + public void addCommand(String moduleName, String commandName, String description) { + insert().value("module", moduleName).value("name", commandName).value("description", description).execute(); + } + + /** + * Deletes a command from the dataset + * + * @param commandName The name of the command you want to delete + * @param subAlias The sub alias of the command you want to delete + */ + public void deleteCommand(String commandName, String subAlias) { + delete().where("name", commandName).where("sub", subAlias).execute(); + } + + /** + * Deletes a command from the dataset + * + * @param commandName The name of the command you want to delete + */ + public void deleteCommand(String commandName) { + delete().where("name", commandName).execute(); + } + + /** + * Clears the list of commands + */ + public void clear() { + delete().execute(); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/GuildManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/GuildManager.java new file mode 100644 index 0000000..9c1d398 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/GuildManager.java @@ -0,0 +1,121 @@ +package xyz.sheepstar.util.bot.manager.sql; + +import de.gnmyt.sqltoolkit.types.SQLType; +import net.dv8tion.jda.api.entities.Guild; +import xyz.sheepstar.util.sql.SheepManager; + +import java.util.HashMap; + +public class GuildManager extends SheepManager { + + @Override + public String tableName() { + return "guilds"; + } + + @Override + public void tableFields() { + custom("guildID").type(SQLType.VARCHAR).length(20).add(); + custom("coins").type(SQLType.INTEGER).length(50).defaultValue("1000").add(); + custom("language").type(SQLType.VARCHAR).length(3).defaultValue("en").add(); + } + + /** + * Checks if a guild is registered + * + * @param guild The guild you want to check + * @return a boolean that says if the guild is registered + */ + public boolean isRegistered(Guild guild) { + return containsRow("guildID", guild.getId()); + } + + /** + * Registers a guild + * + * @param guild The guild you want to register + */ + public void register(Guild guild) { + insert().value("guildID", guild.getId()).execute(); + } + + /** + * Unregisters a guild + * + * @param guild The guild you want to unregister + */ + public void unregister(Guild guild) { + delete("guildID", guild.getId()); + } + + /** + * Gets the language of the guild + * + * @param guild The guild you want to get the language from + * @return the language in lower case + */ + public String getLanguage(Guild guild) { + if (!isRegistered(guild)) register(guild); + return getLowerString("guildID", guild.getId(), "language"); + } + + /** + * Gets the coins of the guild + * + * @param guild The guild you want to get the coins from + * @return the coins of the guild + */ + public String getCoins(Guild guild) { + if (!isRegistered(guild)) register(guild); + return getString("guildID", guild.getId(), "coins"); + } + + /** + * Gets the coins of the guild and parses them to a integer + * + * @param guild The guild you want to get the coins from + * @return the coins of the guild + */ + public int getCoinsInt(Guild guild) { + return Integer.parseInt(getCoins(guild)); + } + + /** + * Gets a lost of all infos about the guild + * + * @param guild The guild you want to get the info from + * @return an info about the guild + */ + public HashMap<String, Object> getInfo(Guild guild) { + if (!isRegistered(guild)) register(guild); + return select().where("guildID", guild.getId()).getResult().getList().get(0); + } + + /** + * Updates the language of the guild + * + * @param guild The guild you want to change the language + * @param toLanguage The new language you want to have + */ + public void updateLanguage(Guild guild, String toLanguage) { + if (!isRegistered(guild)) register(guild); + updateString("guildID", guild.getId(), "language", toLanguage.toLowerCase()); + } + + /** + * Updates coins of the guild + * + * @param guild The guild you want to use + * @param newCoins The new amount of coins you want to set + */ + public void updateCoins(Guild guild, String newCoins) { + if (!isRegistered(guild)) register(guild); + try { + Integer.parseInt(newCoins); + } catch (Exception e) { + newCoins = getCoins(guild); + } + updateString("guildID", guild.getId(), "coins", newCoins); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/LanguageManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/LanguageManager.java new file mode 100644 index 0000000..3d42174 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/LanguageManager.java @@ -0,0 +1,84 @@ +package xyz.sheepstar.util.bot.manager.sql; + +import net.dv8tion.jda.api.entities.Emoji; +import xyz.sheepstar.util.sql.SheepManager; + +import java.util.ArrayList; +import java.util.HashMap; + +public class LanguageManager extends SheepManager { + + @Override + protected String tableName() { + return "languages"; + } + + @Override + protected void tableFields() { + custom("code").length(5).add(); + custom("name").length(25).add(); + custom("emoji").add(); + } + + /** + * Checks if the provided language exists + * + * @param code The language you want to check + * @return a boolean that says if the language is valid/exists + */ + public boolean exists(String code) { + return containsRow("code", code); + } + + /** + * Creates a new language + * + * @param code The language code + * @param name The name of the language + * @param emoji The emoji of the language + */ + public void create(String code, String name, String emoji) { + if (exists(code)) return; + insert().value("code", code).value("name", name.toLowerCase()).value("emoji", emoji).execute(); + } + + /** + * Deletes a language + * + * @param code The language you want to delete + */ + public void delete(String code) { + if (!exists(code)) return; + delete().where("code", code).execute(); + } + + /** + * Gets all languages that currently exists + * + * @return the list of languages + */ + public ArrayList<HashMap<String, Object>> getLanguages() { + return select().getResult().getList(); + } + + /** + * Gets the name of the language + * + * @param code The language code + * @return The name of the language + */ + public String getName(String code) { + return getCamelString("code", code, "name"); + } + + /** + * Gets the emoji from the language + * + * @param code The language you want to get + * @return the emoji + */ + public Emoji getEmoji(String code) { + return Emoji.fromUnicode(getString("code", code, "emoji")); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/ModuleManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/ModuleManager.java new file mode 100644 index 0000000..9642854 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/ModuleManager.java @@ -0,0 +1,136 @@ +package xyz.sheepstar.util.bot.manager.sql; + +import de.gnmyt.sqltoolkit.types.SQLType; +import net.dv8tion.jda.api.entities.Guild; +import xyz.sheepstar.util.sql.SheepManager; + +import java.util.ArrayList; +import java.util.HashMap; + +public class ModuleManager extends SheepManager { + + @Override + protected String tableName() { + return "modules_activated"; + } + + @Override + protected void tableFields() { + custom("moduleID").type(SQLType.VARCHAR).length(255).add(); + custom("guildID").type(SQLType.VARCHAR).length(25).add(); + custom("prefix").type(SQLType.VARCHAR).length(10).add(); + } + + /** + * Checks if the module is enabled + * + * @param guildID The guild you want to check + * @param moduleID The module name + * @return a boolean that says if the module is enabled + */ + public boolean isEnabled(String guildID, String moduleID) { + return select().where("guildID", guildID).where("moduleID", moduleID).getResult().getRowCount() == 1; + } + + /** + * Checks if the module is enabled + * + * @param guild The guild you want to check + * @param moduleID The module name + * @return a boolean that says if the module is enabled + */ + public boolean isEnabled(Guild guild, String moduleID) { + return isEnabled(guild.getId(), moduleID); + } + + /** + * Enables a module on a guild + * + * @param guildID The guild on which you want to enable the module + * @param moduleID The module name + * @param prefix The prefix you want the module to have + */ + public void enableModule(String guildID, String moduleID, String prefix) { + if (isEnabled(guildID, moduleID)) return; + insert().value("guildID", guildID).value("moduleID", moduleID).value("prefix", prefix).execute(); + } + + /** + * Enables a module on a guild + * + * @param guild The guild on which you want to enable the module + * @param moduleID The module name + * @param prefix The prefix you want the module to have + */ + public void enableModule(Guild guild, String moduleID, String prefix) { + enableModule(guild.getId(), moduleID, prefix); + } + + /** + * Disables a module on a guild + * + * @param guildID The guild on which you want to disable the module + * @param moduleID The name of the module + */ + public void disableModule(String guildID, String moduleID) { + if (!isEnabled(guildID, moduleID)) return; + delete().where("guildID", guildID).where("moduleID", moduleID).execute(); + } + + /** + * Disables a module on a guild + * + * @param guild The guild on which you want to disable the module + * @param moduleID The name of the module + */ + public void disableModule(Guild guild, String moduleID) { + disableModule(guild.getId(), moduleID); + } + + /** + * Gets the prefix of an module in a guild + * + * @param guildID The guild you want to get the module prefix from + * @param moduleID The module name + * @return the prefix of the module + */ + public String getPrefix(String guildID, String moduleID) { + if (!isEnabled(guildID, moduleID)) return null; + return select().where("guildID", guildID).where("moduleID", moduleID).getResult().getString("prefix"); + } + + /** + * Updates the prefix of the module + * + * @param guild The guild you want to change the prefix from + * @param moduleID The module you want to change the prefix from + * @param newPrefix The new prefix the module should have + */ + public void updatePrefix(Guild guild, String moduleID, String newPrefix) { + if (!isEnabled(guild, moduleID)) return; + update().where("guildID", guild.getId()).where("moduleID", moduleID).set("prefix", newPrefix).execute(); + } + + /** + * Gets the prefix of an module in a guild + * + * @param guild The guild you want to get the module prefix from + * @param moduleID The module name + * @return the prefix of the module + */ + public String getPrefix(Guild guild, String moduleID) { + return getPrefix(guild.getId(), moduleID); + } + + + /** + * Gets all modules from a guild + * + * @param guild The guild you want to use + * @return a list of modules enabled in the guild + */ + public ArrayList<HashMap<String, Object>> getModules(Guild guild) { + return select().where("guildID", guild.getId()).getResult().getList(); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsInfoManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsInfoManager.java new file mode 100644 index 0000000..07261da --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsInfoManager.java @@ -0,0 +1,140 @@ +package xyz.sheepstar.util.bot.manager.sql; + +import de.gnmyt.sqltoolkit.types.SQLType; +import xyz.sheepstar.util.sql.SheepManager; + +import java.util.ArrayList; +import java.util.HashMap; + +public class SettingsInfoManager extends SheepManager { + + @Override + protected String tableName() { + return "settings_infos"; + } + + @Override + protected void tableFields() { + custom("moduleName").type(SQLType.VARCHAR).length(255).add(); + custom("settingString").type(SQLType.VARCHAR).length(255).add(); + custom("descriptionString").type(SQLType.VARCHAR).length(255).add(); + custom("allowedValues").type(SQLType.VARCHAR).length(255).allowNull(true).add(); + custom("defaultValue").type(SQLType.VARCHAR).length(255).add(); + } + + /** + * Gets all the info settings from the table + * + * @param moduleName The name of the module + * @return a list of all settings + */ + public ArrayList<HashMap<String, Object>> getSettings(String moduleName) { + return select().where("moduleName", moduleName).getResult().getList(); + } + + /** + * Checks if a info exists in the table + * + * @param moduleName The name of the module + * @param setting The name of the setting you want to check + * @return a boolean that says if the info exists in the table + */ + public boolean existsInfo(String moduleName, String setting) { + return select().where("moduleName", moduleName).where("settingString", setting).getResult().getRowCount() == 1; + } + + /** + * Inserts a new info to the table + * + * @param moduleName The name of the module you want to use + * @param setting The name of the setting you want to use + * @param descriptionString The description you want to insert + * @param defaultValue The default value you want to insert + * @param allowedValues The allowed values of the info + */ + public void createInfo(String moduleName, String setting, String descriptionString, String defaultValue, String allowedValues) { + if (existsInfo(moduleName, setting)) return; + insert().value("moduleName", moduleName).value("settingString", setting).value("descriptionString", descriptionString) + .value("defaultValue", defaultValue).value("allowedValues", allowedValues).execute(); + } + + /** + * Deletes a info from the table + * + * @param moduleName The name of the module + * @param setting The setting you want to delete + */ + public void deleteInfo(String moduleName, String setting) { + if (!existsInfo(moduleName, setting)) return; + delete().where("moduleName", moduleName).where("settingString", setting).execute(); + } + + /** + * Gets the description from a setting + * + * @param moduleName The name of the module + * @param setting The setting from which you want the description from + * @return the description of the setting + */ + public String getDescription(String moduleName, String setting) { + return select().where("moduleName", moduleName).where("settingString", setting).getResult().getString("descriptionString"); + } + + /** + * Gets the default value of a setting + * + * @param moduleName The name of the module + * @param setting The setting from which you want the description from + * @return the default value of the setting + */ + public String getDefaultValue(String moduleName, String setting) { + return select().where("moduleName", moduleName).where("settingString", setting).getResult().getString("defaultValue"); + } + + /** + * Gets the allowed values of a string + * + * @param moduleName The name of the module + * @param setting The setting from which you want the values from + * @return the allowed values + */ + public String[] getAllowedValues(String moduleName, String setting) { + String allowedValues = select().where("moduleName", moduleName) + .where("settingString", setting).getResult().getString("allowedValues"); + if (allowedValues == null) return null; + return allowedValues.split(","); + } + + /** + * Checks if a value is allowed + * + * @param moduleName The name of the module + * @param setting The setting you want to check + * @param value The value you want to check + * @return A boolean that says if the value provided is allowed + */ + public boolean isAllowed(String moduleName, String setting, String value) { + String[] allowedValues = getAllowedValues(moduleName, setting); + if (allowedValues == null) return true; + for (String currentValue : allowedValues) + if (value.matches(currentValue)) return true; + return false; + } + + /** + * Gets the allowed values as a string + * + * @param moduleName The name of the module + * @param setting The setting you want to get + * @return The allowed values as a string + */ + public String getAllowedValuesPretty(String moduleName, String setting) { + StringBuilder values = new StringBuilder(); + for (String current : getAllowedValues(moduleName, setting)) { + if (!values.toString().isEmpty()) values.append(", "); + values.append(current); + } + return values.toString(); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsManager.java new file mode 100644 index 0000000..050766c --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/SettingsManager.java @@ -0,0 +1,107 @@ +package xyz.sheepstar.util.bot.manager.sql; + +import de.gnmyt.sqltoolkit.types.SQLType; +import net.dv8tion.jda.api.entities.Guild; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.sql.SheepManager; + +import java.util.HashMap; + +public class SettingsManager extends SheepManager { + + private final SheepstarImpl api = SheepstarCore.getSheepstar(); + + @Override + protected String tableName() { + return "settings"; + } + + @Override + protected void tableFields() { + custom("guildID").type(SQLType.VARCHAR).length(255).add(); + custom("moduleName").type(SQLType.VARCHAR).length(255).add(); + custom("settingString").type(SQLType.VARCHAR).length(255).add(); + custom("settingValue").type(SQLType.VARCHAR).length(255).add(); + } + + /** + * Gets all set settings from a guild + * + * @param guild The guild from which you want the setting from + * @param module The module from which you want the setting from + * @return the settings + */ + public HashMap<String, String> getSettings(Guild guild, String module) { + return select().where("guildID", guild.getId()).where("moduleName", module).getResult() + .getMultipleList("settingString", "settingValue"); + } + + /** + * Checks if a setting exists + * + * @param guild The guild from which you want the setting from + * @param module The module from which you want the setting from + * @param setting The setting you want to check + * @return a boolean that says if the setting exists + */ + public boolean existsSetting(Guild guild, String module, String setting) { + return select().where("guildID", guild.getId()).where("moduleName", module).where("settingString", setting).getResult().getRowCount() == 1; + } + + /** + * Gets a setting from a guild + * + * @param guild The guild from which you want the setting from + * @param module The module from which you want the setting from + * @param setting The setting you want to get + * @return the value of the setting + */ + public Object getSetting(Guild guild, String module, String setting) { + if (!existsSetting(guild, module, setting)) + updateSetting(guild, module, setting, api.getBotManager().getSettingsInfoManager().getDefaultValue(module, setting)); + return select().where("moduleName", module).where("guildID", guild.getId()).where("settingString", setting) + .getResult().getObject("settingValue"); + } + + /** + * Gets a setting from a guild in the form of a string + * + * @param guild The guild from which you want the setting from + * @param module The module from which you want the setting from + * @param setting The setting you want to get + * @return the value of the setting in form of a string + */ + public String getSettingString(Guild guild, String module, String setting) { + return getSetting(guild, module, setting).toString(); + } + + /** + * Inserts a setting into the table + * + * @param guild The guild you want to use + * @param module The module you want to use + * @param setting The setting you want to insert + * @param value The value you want to insert + */ + public void insertSetting(Guild guild, String module, String setting, String value) { + insert().value("guildID", guild.getId()).value("moduleName", module).value("settingString", setting) + .value("settingValue", value).execute(); + } + + /** + * Updates a setting from this table + * + * @param guild The guild you want to use + * @param module The module you want to use + * @param setting The setting you want to use + * @param value The value you want to update + */ + public void updateSetting(Guild guild, String module, String setting, String value) { + if (existsSetting(guild, module, setting)) { + update().where("moduleName", module).where("guildID", guild.getId()).where("settingString", setting) + .set("settingValue", value).execute(); + } else insertSetting(guild, module, setting, value); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/TranslationManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/TranslationManager.java new file mode 100644 index 0000000..450eb6c --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/manager/sql/TranslationManager.java @@ -0,0 +1,100 @@ +package xyz.sheepstar.util.bot.manager.sql; + +import de.gnmyt.sqltoolkit.types.SQLType; +import xyz.sheepstar.util.sql.SheepManager; + +import java.util.HashMap; + +public class TranslationManager extends SheepManager { + + @Override + protected String tableName() { + return "translations"; + } + + @Override + protected void tableFields() { + string("translationCode", 999, false, ""); + custom("languageCode").type(SQLType.VARCHAR).length(5).defaultValue("en").add(); + string("translation", 999, false, ""); + } + + /** + * Checks if a translationCode is registered + * + * @param translationCode The translation string/code + * @param languageCode The language you want to check + * @return a boolean that says if the language is registered + */ + public boolean isRegistered(String translationCode, String languageCode) { + return select() + .where("translationCode", translationCode) + .where("languageCode", languageCode) + .getResult().getRowCount() == 1; + } + + /** + * Inserts a translation + * + * @param translationCode The translation code/string + * @param toLanguage The language you want to translate + * @param translation The translation itself + */ + public void translate(String translationCode, String toLanguage, String translation) { + if (isRegistered(translationCode, toLanguage)) return; + insert() + .value("translationCode", translationCode) + .value("languageCode", toLanguage) + .value("translation", translation) + .execute(); + } + + /** + * Inserts a translation with defaults to english + * + * @param translationCode The translation code/string + * @param translation The translation itself + */ + public void translate(String translationCode, String translation) { + translate(translationCode, "en", translation); + } + + /** + * Deletes a translation by id + * + * @param id The id of the translation + */ + public void deleteTranslation(int id) { + if (containsRow("id", id)) delete("id", id); + } + + /** + * Deletes a translation by code + * + * @param translationCode The translation code/string + * @param toLanguage The language + */ + public void deleteTranslation(String translationCode, String toLanguage) { + if (isRegistered(translationCode, toLanguage)) + delete().where("translationCode", translationCode).where("languageCode", toLanguage).execute(); + } + + /** + * Gets a translation from a string + * + * @param translationString The translation code/string + * @param languageCode The language you want to get the translation from + * @param variables The objects you want to add to your translation + * @return the translation + */ + public String getTranslation(String translationString, String languageCode, Object... variables) { + HashMap<String, String> result = select().where("translationCode", translationString).getResult().getMultipleList("languageCode", "translation"); + if (result.isEmpty()) return "${{" + translationString + "}}"; + if (result.containsKey(languageCode)) + return String.format(result.get(languageCode), variables).replace("\\n", "\n"); + if (!languageCode.equals("en") && result.containsKey("en")) + return String.format(result.get("en"), variables).replace("\\n", "\n"); + return "${{" + translationString + "}}"; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/permission/PermissionNode.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/permission/PermissionNode.java new file mode 100644 index 0000000..e2ae6a9 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/permission/PermissionNode.java @@ -0,0 +1,11 @@ +package xyz.sheepstar.util.bot.permission; + +public enum PermissionNode { + + ADMINISTRATOR, + SUPPORTER, + BOT_OWNER, + SERVER_OWNER, + DEFAULT + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/updater/StatusUpdater.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/updater/StatusUpdater.java new file mode 100644 index 0000000..e839327 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/bot/updater/StatusUpdater.java @@ -0,0 +1,107 @@ +package xyz.sheepstar.util.bot.updater; + +import net.dv8tion.jda.api.entities.Activity; +import xyz.sheepstar.util.SheepstarImpl; + +import java.util.ArrayList; + +public class StatusUpdater { + + private final SheepstarImpl api; + private final ArrayList<Activity> activities; + private int time = 15000; + private Thread updateThread; + + /** + * The default constructor of the StatusUpdater + * + * @param api The Sheepstar instance + */ + public StatusUpdater(SheepstarImpl api) { + this.api = api; + activities = new ArrayList<>(); + } + + /** + * Adds a activity to the status updater + * + * @param activity The activity you want to add + */ + public void addActivity(Activity activity) { + activities.add(activity); + } + + /** + * Removes a activity from the status updater + * + * @param element The id of the activity you want to remove + */ + public void removeActivity(int element) { + activities.remove(element); + } + + /** + * Clears all activities from the status updater + */ + public void clearActivity() { + activities.clear(); + } + + /** + * Stops the status updating thread + */ + public void stop() { + if (isRunning()) { + updateThread.interrupt(); + updateThread = null; + } + } + + /** + * Starts the status updating thread + */ + public void start() { + if (!isRunning()) { + updateThread = new Thread(this::run); + updateThread.setName("StatusUpdater"); + updateThread.start(); + } + } + + /** + * Runs the status updating logic + */ + private void run() { + if (activities.size() > 0) + for (Activity activity : activities) { + try { + api.getJDA().getPresence().setActivity(activity); + Thread.sleep(time); + } catch (Exception ignored) { + } + } + try { + Thread.sleep(2000); + } catch (Exception ignored) { + } + run(); + } + + /** + * Checks if the updating thread is running + * + * @return a boolean that says if the update thread is running + */ + public boolean isRunning() { + return updateThread != null; + } + + /** + * Sets the time every message changes in ms + * + * @param time The time you want to change + */ + public void setTime(int time) { + this.time = time; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/CommandConfiguration.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/CommandConfiguration.java new file mode 100644 index 0000000..4f8408f --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/CommandConfiguration.java @@ -0,0 +1,64 @@ +package xyz.sheepstar.util.configuration; + +public class CommandConfiguration { + + private final boolean pingEnabled; + private final boolean prefixEnabled; + private final boolean slashEnabled; + private final String debugGuild; + + /** + * Constructor of the {@link CommandConfiguration} + * + * @param pingEnabled Is the ping feature enabled? + * If so, the bot will react to pings + * @param prefixEnabled Is the prefix feature enabled? + * If so, the bot will react to prefix commands + * @param slashEnabled Is the slash command feature enabled? + * If so, the bot is able to use slash commands + * @param debugGuild If you want to, you can set a debug guild. + * It helps you to register commands faster + */ + public CommandConfiguration(boolean pingEnabled, boolean prefixEnabled, boolean slashEnabled, String debugGuild) { + this.pingEnabled = pingEnabled; + this.prefixEnabled = prefixEnabled; + this.slashEnabled = slashEnabled; + this.debugGuild = debugGuild; + } + + /** + * Is the ping feature enabled? + * + * @return <code>true</code> if the ping feature is enabled, otherwise <code>false</code> + */ + public boolean isPingEnabled() { + return pingEnabled; + } + + /** + * Is the prefix feature enabled? + * + * @return <code>true</code> if the prefix feature is enabled, otherwise <code>false</code> + */ + public boolean isPrefixEnabled() { + return prefixEnabled; + } + + /** + * Is the slash feature enabled? + * + * @return <code>true</code> if the slash feature is enabled, otherwise <code>false</code> + */ + public boolean isSlashEnabled() { + return slashEnabled; + } + + /** + * Gets the debug guild + * + * @return the debug guild + */ + public String getDebugGuild() { + return debugGuild; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/DatabaseConfiguration.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/DatabaseConfiguration.java new file mode 100644 index 0000000..dfa7a6e --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/DatabaseConfiguration.java @@ -0,0 +1,60 @@ +package xyz.sheepstar.util.configuration; + +public class DatabaseConfiguration { + + private final String hostname; + private final String username; + private final String password; + private final String database; + + /** + * Constructor of the {@link DatabaseConfiguration} + * + * @param hostname The hostname of your mysql connection + * @param username The username of your mysql connection + * @param password The password of your mysql connection + * @param database The database of your mysql connection + */ + public DatabaseConfiguration(String hostname, String username, String password, String database) { + this.hostname = hostname; + this.username = username; + this.password = password; + this.database = database; + } + + /** + * Gets the hostname of your mysql database + * + * @return the database hostname + */ + public String getHostname() { + return hostname; + } + + /** + * Gets the username of your mysql database + * + * @return the database username + */ + public String getUsername() { + return username; + } + + /** + * Gets the password of the mysql database + * + * @return the database password + */ + public String getPassword() { + return password; + } + + /** + * Gets the database name of the mysql database + * + * @return the database name + */ + public String getDatabase() { + return database; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/PermissionConfiguration.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/PermissionConfiguration.java new file mode 100644 index 0000000..c3a1be4 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/PermissionConfiguration.java @@ -0,0 +1,37 @@ +package xyz.sheepstar.util.configuration; + +public class PermissionConfiguration { + + private final String[] botOwner; + private final SupporterPermissionConfiguration supporterPermissionConfiguration; + + /** + * Constructor of the {@link PermissionConfiguration} + * + * @param botOwner All bot owners. + * Used to check permissions of a user + * @param supporterPermissionConfiguration The supporter permission configuration that needs to be set up + */ + public PermissionConfiguration(String[] botOwner, SupporterPermissionConfiguration supporterPermissionConfiguration) { + this.botOwner = botOwner; + this.supporterPermissionConfiguration = supporterPermissionConfiguration; + } + + /** + * Gets all owners of the bot + * + * @return all owners of the bot + */ + public String[] getBotOwner() { + return botOwner; + } + + /** + * Gets the supporter configuration + * + * @return the supporter configuration + */ + public SupporterPermissionConfiguration getSupporter() { + return supporterPermissionConfiguration; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SheepstarConfiguration.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SheepstarConfiguration.java new file mode 100644 index 0000000..534a500 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SheepstarConfiguration.java @@ -0,0 +1,128 @@ +package xyz.sheepstar.util.configuration; + +import xyz.sheepstar.util.configuration.entity.SheepstarActivity; +import xyz.sheepstar.util.configuration.entity.SheepstarPool; + +import java.util.ArrayList; + +public class SheepstarConfiguration { + + private final String token; + private final String apiUrl; + private final String apiKey; + private final String moduleDirectory; + + private final DatabaseConfiguration databaseConfiguration; + private final CommandConfiguration commandConfiguration; + private final PermissionConfiguration permissionConfiguration; + private final ArrayList<SheepstarActivity> activities; + private final ArrayList<SheepstarPool> pools; + + /** + * Constructor of the {@link SheepstarConfiguration} + * + * @param token The token the sheepstar bot should connect to + * @param apiUrl The api url the sheepstar bot should connect to + * @param apiKey The sheepstar api key the bot should use to get something from the server + * @param moduleDirectory The directory your modules are in + * @param databaseConfiguration The database configuration you have to set up + * @param commandConfiguration The command configuration you have to set up + * @param permissionConfiguration The permission configuration you have to set up + * @param activities The activities you want to load + * @param pools The pools you want to use + */ + public SheepstarConfiguration(String token, String apiUrl, String apiKey, String moduleDirectory, DatabaseConfiguration databaseConfiguration, + CommandConfiguration commandConfiguration, PermissionConfiguration permissionConfiguration, + ArrayList<SheepstarActivity> activities, ArrayList<SheepstarPool> pools) { + this.token = token; + this.apiUrl = apiUrl; + this.apiKey = apiKey; + this.moduleDirectory = moduleDirectory; + this.databaseConfiguration = databaseConfiguration; + this.commandConfiguration = commandConfiguration; + this.permissionConfiguration = permissionConfiguration; + this.activities = activities; + this.pools = pools; + } + + /** + * Gets the sheepstar bot token + * + * @return the sheepstar bot token + */ + public String getToken() { + return token; + } + + /** + * Gets the sheepstar api url + * + * @return the sheepstar api url + */ + public String getApiUrl() { + return apiUrl; + } + + /** + * Gets the sheepstar api key + * + * @return the sheepstar api key + */ + public String getApiKey() { + return apiKey; + } + + /** + * Gets the module directory in which all modules are located in + * + * @return the module directory + */ + public String getModuleDirectory() { + return moduleDirectory; + } + + /** + * Gets the database configuration with all needed database parameters + * + * @return the database configuration + */ + public DatabaseConfiguration getDatabaseConfiguration() { + return databaseConfiguration; + } + + /** + * Gets the command configuration with all needed command parameters + * + * @return the command configuration + */ + public CommandConfiguration getCommandConfiguration() { + return commandConfiguration; + } + + /** + * Gets the permission configuration with all needed permission parameters + * + * @return the permission configuration + */ + public PermissionConfiguration getPermissionConfiguration() { + return permissionConfiguration; + } + + /** + * Gets the activities that should be loaded + * + * @return the activities + */ + public ArrayList<SheepstarActivity> getActivities() { + return activities; + } + + /** + * Gets the pools that should be used + * + * @return the pools + */ + public ArrayList<SheepstarPool> getPools() { + return pools; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SupporterPermissionConfiguration.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SupporterPermissionConfiguration.java new file mode 100644 index 0000000..8242d6b --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/SupporterPermissionConfiguration.java @@ -0,0 +1,36 @@ +package xyz.sheepstar.util.configuration; + +public class SupporterPermissionConfiguration { + + private final String guildID; + private final String roleID; + + /** + * Constructor of the {@link SupporterPermissionConfiguration} + * + * @param guildID The guild id in which the supporter role is located in + * @param roleID The role id to check which user is a supporter + */ + public SupporterPermissionConfiguration(String guildID, String roleID) { + this.guildID = guildID; + this.roleID = roleID; + } + + /** + * Gets the guild id + * + * @return the guild id + */ + public String getGuildID() { + return guildID; + } + + /** + * Gets the role id + * + * @return the role id + */ + public String getRoleID() { + return roleID; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarActivity.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarActivity.java new file mode 100644 index 0000000..8fcde41 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarActivity.java @@ -0,0 +1,38 @@ +package xyz.sheepstar.util.configuration.entity; + +import net.dv8tion.jda.api.entities.Activity; + +public class SheepstarActivity { + + private final Activity.ActivityType type; + private final String name; + + /** + * Constructor of the {@link SheepstarActivity} + * + * @param type The type of the activity + * @param name The name of the activity + */ + public SheepstarActivity(Activity.ActivityType type, String name) { + this.type = type; + this.name = name; + } + + /** + * Gets the type of the activity + * + * @return the type of the activity + */ + public Activity.ActivityType getType() { + return type; + } + + /** + * Gets the name of the activity + * + * @return the name of the activity + */ + public String getName() { + return name; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarPool.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarPool.java new file mode 100644 index 0000000..df32609 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/configuration/entity/SheepstarPool.java @@ -0,0 +1,36 @@ +package xyz.sheepstar.util.configuration.entity; + +public class SheepstarPool { + + private final String poolName; + private final int corePoolSize; + + /** + * Constructor of the {@link SheepstarPool} + * + * @param poolName The name of the pool + * @param corePoolSize The core pool size + */ + public SheepstarPool(String poolName, int corePoolSize) { + this.poolName = poolName; + this.corePoolSize = corePoolSize; + } + + /** + * Get the name of the pool + * + * @return the name of the pool + */ + public String getPoolName() { + return poolName; + } + + /** + * Get the core pool size + * + * @return the core pool size + */ + public int getCorePoolSize() { + return corePoolSize; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommand.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommand.java new file mode 100644 index 0000000..6b562e8 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommand.java @@ -0,0 +1,83 @@ +package xyz.sheepstar.util.console; + +import org.slf4j.Logger; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.log.LogManager; + +import java.util.ArrayList; +import java.util.List; + +public abstract class ConsoleCommand { + + private final Logger LOG = LogManager.getLog(ConsoleManager.class); + + protected SheepstarImpl api = SheepstarCore.getSheepstar(); + + ArrayList<ConsoleCommandField> usage = new ArrayList<>(); + + { + usage(); + } + + /** + * Gets the aliases of the command + * + * @return the aliases of the command + */ + public abstract List<String> getAlias(); + + /** + * Runs when the validation was successful + * + * @param args The list of arguments + */ + public abstract void onExecute(String[] args); + + /** + * Runs when the alias matches an alias from the list + * + * @param args The list of arguments + */ + public void run(String[] args) { + + if (!usage.isEmpty() && !isUsageValid(args)) { + LOG.error("Wrong usage! Please use: " + getAlias().get(0) + " " + getUsagePretty()); + return; + } + + onExecute(args); + } + + public boolean isUsageValid(String[] args) { + for (int i = 0; i < usage.size(); i++) { + ConsoleCommandField field = usage.get(i); + if (field.isRequired() && args.length <= i) return false; + if (args.length <= i) continue; + + if (field.getLength() != -1 && field.getLength() < args[i].length()) return false; + } + return true; + } + + public String getUsagePretty() { + StringBuilder usageString = new StringBuilder(); + usage.forEach(usage -> { + if (!usageString.toString().isEmpty()) usageString.append(" "); + String chars = usage.isRequired() ? "<%s>" : "[%s]"; + usageString.append(String.format(chars, usage.getName())); + }); + return usageString.toString(); + } + + /** + * Provides the usage of the command + */ + public void usage() { + + } + + public void usage(String name, int length, boolean isRequired) { + usage.add(new ConsoleCommandField(name, length, isRequired)); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommandField.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommandField.java new file mode 100644 index 0000000..ba7769f --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleCommandField.java @@ -0,0 +1,76 @@ +package xyz.sheepstar.util.console; + +public class ConsoleCommandField { + + private String name; + private int length; + private boolean isRequired; + + /** + * Basic constructor for the CommandUsage + * + * @param name The name of the usage field + * @param length The length of the usage field + * @param isRequired Is the field required? + */ + public ConsoleCommandField(String name, int length, boolean isRequired) { + this.name = name; + this.length = length; + this.isRequired = isRequired; + } + + /** + * Gets the field name + * + * @return the field name + */ + public String getName() { + return name; + } + + /** + * Sets the field name + * + * @param name The new field name + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the field length + * + * @return Gets the field length + */ + public int getLength() { + return length; + } + + /** + * Sets the field length + * + * @param length The new field length + */ + public void setLength(int length) { + this.length = length; + } + + /** + * Is the field required? + * + * @return a boolean that says if the field is required + */ + public boolean isRequired() { + return isRequired; + } + + /** + * Sets the fields required field + * + * @param required Is the field required? + */ + public void setRequired(boolean required) { + isRequired = required; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleListenerThread.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleListenerThread.java new file mode 100644 index 0000000..4da4fea --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleListenerThread.java @@ -0,0 +1,33 @@ +package xyz.sheepstar.util.console; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.event.console.ConsoleMessageReceivedEvent; + +import java.util.Scanner; + +public class ConsoleListenerThread extends Thread { + + private final SheepstarImpl api; + private final Scanner scanner = new Scanner(System.in); + + /** + * Basic constructor of the console listener thread + * + * @param api The sheepstar instance + */ + public ConsoleListenerThread(SheepstarImpl api) { + super("ConsoleListenerThread"); + api.getEventManager().addEventListener(new ConsoleMessageReceivedListener()); + this.api = api; + } + + /** + * Runs an ConsoleMessageReceivedEvent as soon as a message has been sent + */ + @Override + public void run() { + while (true) { + new ConsoleMessageReceivedEvent(api, scanner.nextLine()).call(); + } + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleManager.java new file mode 100644 index 0000000..df960d7 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleManager.java @@ -0,0 +1,96 @@ +package xyz.sheepstar.util.console; + +import org.slf4j.Logger; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.bot.command.GuildCommand; +import xyz.sheepstar.util.log.LogManager; + +import java.util.ArrayList; +import java.util.Arrays; + +public class ConsoleManager { + + private final Logger LOG = LogManager.getLog(ConsoleManager.class); + private final ArrayList<ConsoleCommand> REGISTERED_COMMANDS = new ArrayList<>(); + private final SheepstarImpl api; + private final ConsoleListenerThread listenerThread; + + /** + * Basic constructor of the console manager + * + * @param api The sheepstar instance + */ + public ConsoleManager(SheepstarImpl api) { + this.api = api; + listenerThread = new ConsoleListenerThread(api); + listenerThread.start(); + + registerDefaultCommands(); + } + + /** + * Registers all the default commands provided by the system / api + */ + private void registerDefaultCommands() { + + } + + /** + * Registers a console command + * + * @param command The command you want to register + */ + public void register(ConsoleCommand... command) { + REGISTERED_COMMANDS.addAll(Arrays.asList(command)); + } + + /** + * Runs when the user executes an command + * + * @param command The command + */ + public void run(String command) { + for (ConsoleCommand current : REGISTERED_COMMANDS) { + if (isValidCommand(command, current)) { + current.run(getArgs(command)); + return; + } + } + LOG.error("Command not found"); + } + + /** + * Validates the command + * + * @param commandText The text you want to validate + * @param command The command you want to check + * @return an boolean that says if the command is valid + */ + private boolean isValidCommand(String commandText, ConsoleCommand command) { + String lowerText = commandText.toLowerCase(); + if (lowerText.contains(" ")) lowerText = lowerText.substring(0, lowerText.indexOf(" ")); + if (lowerText.contains("\n")) lowerText.substring(0, lowerText.indexOf("\n")); + return command.getAlias().contains(lowerText); + } + + /** + * Get the arguments from an String + * + * @param message The string you want to get the arguments from + * @return the list of arguments + */ + private String[] getArgs(String message) { + ArrayList<String> parts = GuildCommand.getPartsFromInput(message); + parts.remove(0); + return parts.toArray(new String[0]); + } + + /** + * Gets the registered commands + * + * @return the registered commands + */ + public ArrayList<ConsoleCommand> getRegisteredCommands() { + return REGISTERED_COMMANDS; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleMessageReceivedListener.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleMessageReceivedListener.java new file mode 100644 index 0000000..6c68335 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/console/ConsoleMessageReceivedListener.java @@ -0,0 +1,19 @@ +package xyz.sheepstar.util.console; + +import xyz.sheepstar.util.event.api.EventListener; +import xyz.sheepstar.util.event.api.Listener; +import xyz.sheepstar.util.event.console.ConsoleMessageReceivedEvent; + +public class ConsoleMessageReceivedListener implements Listener { + + /** + * Gets executes when a user writes a message in the console + * + * @param event The event that happens + */ + @EventListener + public void handle(ConsoleMessageReceivedEvent event) { + event.getAPI().getConsoleManager().run(event.getMessage()); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/SheepstarEvent.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/SheepstarEvent.java new file mode 100644 index 0000000..02191aa --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/SheepstarEvent.java @@ -0,0 +1,43 @@ +package xyz.sheepstar.util.event; + +import xyz.sheepstar.util.Sheepstar; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.event.api.EventData; + +import java.util.ArrayList; + +public class SheepstarEvent { + + private final SheepstarImpl api; + + /** + * The basic constructor of the event that happens <b>anytime a event has been called</b> + * + * @param api The sheepstar instance + */ + public SheepstarEvent(SheepstarImpl api) { + this.api = api; + } + + /** + * Calls the event + */ + public void call() { + final ArrayList<EventData> eventList = api.getEventManager().getEvents(this.getClass()); + if (eventList == null) return; + for (EventData data : eventList) + try { + data.method.invoke(data.object, this); + } catch (Exception ignored) { + } + } + + /** + * Gets the sheepstar instance + * + * @return the sheepstar instance + */ + public Sheepstar getAPI() { + return api; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventData.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventData.java new file mode 100644 index 0000000..690da82 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventData.java @@ -0,0 +1,21 @@ +package xyz.sheepstar.util.event.api; + +import java.lang.reflect.Method; + +public class EventData { + + public final Object object; + public final Method method; + + /** + * The basic constructor of the EventData + * + * @param object The registered event object + * @param method The registered event method + */ + public EventData(Object object, Method method) { + this.object = object; + this.method = method; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventListener.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventListener.java new file mode 100644 index 0000000..a6b043e --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventListener.java @@ -0,0 +1,11 @@ +package xyz.sheepstar.util.event.api; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +public @interface EventListener { +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventManager.java new file mode 100644 index 0000000..3621324 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/EventManager.java @@ -0,0 +1,93 @@ +package xyz.sheepstar.util.event.api; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.event.SheepstarEvent; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +public class EventManager { + + private final SheepstarImpl api; + private final Map<Class<? extends SheepstarEvent>, ArrayList<EventData>> REGISTERED_EVENTS = new HashMap<>(); + + /** + * The basic constructor of the event manager + * + * @param api The sheepstar instance + */ + public EventManager(SheepstarImpl api) { + this.api = api; + } + + /** + * Checks if the method is valid (contains the EventListener annotation) + * + * @param method The method you want to check + * @return a boolean that says if the method is valid + */ + private boolean isValidMethod(final Method method) { + return method.getParameterTypes().length == 1 || method.isAnnotationPresent(EventListener.class); + } + + /** + * Adds an event listener + * + * @param o The listener you want to add + */ + public void addEventListener(Listener o) { + for (final Method method : o.getClass().getMethods()) if (isValidMethod(method)) register(method, o); + } + + /** + * Removes an event listener + * + * @param o The listener you want to add + */ + public void removeEventListener(Listener o) { + for (ArrayList<EventData> registeredEvents : REGISTERED_EVENTS.values()) + for (int i = registeredEvents.size() - 1; i >= 0; i--) + if (registeredEvents.get(i).object.equals(o)) registeredEvents.remove(i); + cleanEventList(); + } + + /** + * Registers a method + * + * @param method The method you want to register + * @param o The listener you want to register + */ + private void register(final Method method, final Listener o) { + final Class<?> clazz = method.getParameterTypes()[0]; + final EventData methodData = new EventData(o, method); + if (!methodData.method.isAccessible()) methodData.method.setAccessible(true); + if (REGISTERED_EVENTS.containsKey(clazz)) { + if (!REGISTERED_EVENTS.get(clazz).contains(methodData)) REGISTERED_EVENTS.get(clazz).add(methodData); + } else { + REGISTERED_EVENTS.put((Class<? extends SheepstarEvent>) clazz, new ArrayList<EventData>() {{ + this.add(methodData); + }}); + } + } + + /** + * Gets a list of the events mapped to a class + * + * @param clazz A class which extends the SheepstarEvent + * @return The list of the events + */ + public ArrayList<EventData> getEvents(final Class<? extends SheepstarEvent> clazz) { + return REGISTERED_EVENTS.get(clazz); + } + + /** + * Clears the event list + */ + private void cleanEventList() { + REGISTERED_EVENTS.entrySet().removeIf(classArrayListEntry -> classArrayListEntry.getValue().isEmpty()); + } + + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/Listener.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/Listener.java new file mode 100644 index 0000000..5e92624 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/api/Listener.java @@ -0,0 +1,4 @@ +package xyz.sheepstar.util.event.api; + +public interface Listener { +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleEvent.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleEvent.java new file mode 100644 index 0000000..77a16a9 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleEvent.java @@ -0,0 +1,17 @@ +package xyz.sheepstar.util.event.console; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.event.SheepstarEvent; + +public class ConsoleEvent extends SheepstarEvent { + + /** + * The basic constructor of the Console Event + * + * @param api The sheepstar instance + */ + public ConsoleEvent(SheepstarImpl api) { + super(api); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleMessageReceivedEvent.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleMessageReceivedEvent.java new file mode 100644 index 0000000..62c78af --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/console/ConsoleMessageReceivedEvent.java @@ -0,0 +1,29 @@ +package xyz.sheepstar.util.event.console; + +import xyz.sheepstar.util.SheepstarImpl; + +public class ConsoleMessageReceivedEvent extends ConsoleEvent { + + private final String message; + + /** + * The basic constructor of the Console Event, + * it happens when a console message has been received + * + * @param api The sheepstar instance + * @param message The message of the received event + */ + public ConsoleMessageReceivedEvent(SheepstarImpl api, String message) { + super(api); + this.message = message; + } + + /** + * Gets the message received + * + * @return the received message + */ + public String getMessage() { + return message; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleEvent.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleEvent.java new file mode 100644 index 0000000..5e13313 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleEvent.java @@ -0,0 +1,30 @@ +package xyz.sheepstar.util.event.module; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.event.SheepstarEvent; +import xyz.sheepstar.util.module.Module; + +public class ModuleEvent extends SheepstarEvent { + + Module module; + + /** + * The basic constructor of the ModuleEvent + * + * @param api The sheepstar instance + * @param module The module + */ + public ModuleEvent(SheepstarImpl api, Module module) { + super(api); + this.module = module; + } + + /** + * Gets the module of the event + * + * @return the module + */ + public Module getModule() { + return module; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadedEvent.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadedEvent.java new file mode 100644 index 0000000..e2310be --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadedEvent.java @@ -0,0 +1,18 @@ +package xyz.sheepstar.util.event.module; + + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.module.Module; + +public class ModuleLoadedEvent extends ModuleEvent { + + /** + * The basic constructor of the event that happens when a module has been loaded + * + * @param api The sheepstar instance + * @param module The module + */ + public ModuleLoadedEvent(SheepstarImpl api, Module module) { + super(api, module); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadingEvent.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadingEvent.java new file mode 100644 index 0000000..91e5e25 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/event/module/ModuleLoadingEvent.java @@ -0,0 +1,17 @@ +package xyz.sheepstar.util.event.module; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.module.Module; + +public class ModuleLoadingEvent extends ModuleEvent { + + /** + * The basic constructor of the event that happens when a module is loading + * + * @param api The sheepstar instance + * @param module The module + */ + public ModuleLoadingEvent(SheepstarImpl api, Module module) { + super(api, module); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Endpoint.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Endpoint.java new file mode 100644 index 0000000..4743832 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Endpoint.java @@ -0,0 +1,100 @@ +package xyz.sheepstar.util.http.client; + +import static xyz.sheepstar.util.http.client.RequestMethod.*; + +public class Endpoint { + + private final RequestMethod method; + private final String path; + + /** + * Constructor of the {@link Endpoint} + * + * @param method The request method + * @param path The path of the endpoint + */ + public Endpoint(RequestMethod method, String path) { + this.method = method; + this.path = path; + } + + /** + * Gets the request method + * + * @return the request method + */ + public RequestMethod getMethod() { + return method; + } + + /** + * Gets the path of the endpoint + * + * @return the path of the endpoint + */ + public String getPath() { + return path; + } + + public static class ApiKey { + public final static Endpoint CREATE_KEY = new Endpoint(PUT, "apikey"); + + public final static Endpoint GET_KEY = new Endpoint(GET, "apikey/{api_key}"); + + public final static Endpoint DELETE_KEY = new Endpoint(DELETE, "apikey/{api_key}"); + } + + public static class Article { + public final static Endpoint CREATE_ARTICLE = new Endpoint(PUT, "article"); + + public final static Endpoint DELETE_ARTICLE = new Endpoint(DELETE, "article"); + + public final static Endpoint GET_ARTICLE = new Endpoint(GET, "article/{article_id}"); + + public final static Endpoint FIND_ARTICLE = new Endpoint(GET, "article/{module_name}/{article_id}"); + + public final static Endpoint LIST_ARTICLES = new Endpoint(GET, "article/{module_name}/list"); + } + + public static class Gift { + public final static Endpoint CREATE_GIFT = new Endpoint(PUT, "gift"); + + public final static Endpoint GET_GIFT = new Endpoint(GET, "gift/{gift_id}"); + + public final static Endpoint DELETE_GIFT = new Endpoint(DELETE, "gift/{gift_id}"); + + public final static Endpoint UPDATE_GIFT = new Endpoint(PATCH, "gift"); + + public final static Endpoint REDEEM_CODE = new Endpoint(POST, "gift/redeem"); + } + + public static class Link { + public final static Endpoint CREATE_LINK = new Endpoint(PUT, "link"); + + public final static Endpoint DELETE_LINK = new Endpoint(DELETE, "link/{code}"); + + public final static Endpoint GET_LINK = new Endpoint(GET, "link/{code}"); + } + + public static class Media { + public final static Endpoint UPLOAD_MEDIA = new Endpoint(PUT, "media"); + + public final static Endpoint DELETE_MEDIA = new Endpoint(DELETE, "media/{asset_id}"); + + public final static Endpoint GET_MEDIA = new Endpoint(GET, "media/{asset_id}"); + } + + public static class Shop { + public final static Endpoint GET_ITEMS = new Endpoint(GET, "shop"); + + public final static Endpoint OWNS_ITEM = new Endpoint(GET, "shop/owns"); + + public final static Endpoint DEACTIVATE_ITEM = new Endpoint(DELETE, "shop"); + + public final static Endpoint ACTIVATE_ITEM = new Endpoint(PUT, "shop"); + } + + public static class User { + public final static Endpoint GET_GUILDS = new Endpoint(GET, "user/guilds"); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/ErrorResponse.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/ErrorResponse.java new file mode 100644 index 0000000..53f9e9d --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/ErrorResponse.java @@ -0,0 +1,26 @@ +package xyz.sheepstar.util.http.client; + +public class ErrorResponse extends Response { + + private String message; + + /** + * Constructor of the {@link ErrorResponse} + * + * @param response The response from the {@link Requester} + */ + public ErrorResponse(okhttp3.Response response) { + super(response); + if (response == null) return; + message = getData().getString("message"); + } + + /** + * Returns the error message + * + * @return the error message + */ + public String getMessage() { + return message; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Request.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Request.java new file mode 100644 index 0000000..a4cc578 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Request.java @@ -0,0 +1,77 @@ +package xyz.sheepstar.util.http.client; + +import net.dv8tion.jda.api.utils.data.DataObject; +import okhttp3.MediaType; +import okhttp3.RequestBody; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +import java.util.concurrent.CompletableFuture; + +public class Request<T> { + + private final Route route; + private final DataObject data; + private final CompletableFuture<? super T> onSuccess; + private final RestActionImpl<T> restAction; + + /** + * Constructor of the {@link Request} + * + * @param route The route of the request + * @param data The data of the request + * @param onSuccess The {@link CompletableFuture} that will be completed when the request is successful + * @param restAction The {@link RestActionImpl} that will be executed + */ + public Request(Route route, DataObject data, CompletableFuture<? super T> onSuccess, RestActionImpl<T> restAction) { + this.route = route; + this.data = data; + this.onSuccess = onSuccess; + this.restAction = restAction; + } + + /** + * Handles the successful response of the {@link Request} + * + * @param response The {@link okhttp3.Response} from the request + */ + public void handleSuccess(okhttp3.Response response) { + onSuccess.complete(restAction.handle(new Response(response))); + } + + /** + * Handles the failure of the {@link Request} + * + * @param response The {@link okhttp3.Response} from the request + */ + public void handleError(okhttp3.Response response) { + onSuccess.complete(restAction.handle(new ErrorResponse(response))); + } + + /** + * Gets the {@link Route} of the {@link Request} + * + * @return The {@link Route} + */ + public Route getRoute() { + return route; + } + + /** + * Gets the data of the {@link Request} + * + * @return The {@link DataObject} + */ + public DataObject getData() { + return data; + } + + /** + * Converts the {@link Request} to a {@link RequestBody} + * + * @return the {@link RequestBody} + */ + public RequestBody convertToBody() { + return data != null ? RequestBody.create(data.toJson(), MediaType.parse("application/json; charset=utf-8")) : null; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RequestMethod.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RequestMethod.java new file mode 100644 index 0000000..466e2e1 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RequestMethod.java @@ -0,0 +1,11 @@ +package xyz.sheepstar.util.http.client; + +public enum RequestMethod { + + GET, + POST, + PUT, + DELETE, + PATCH + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Requester.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Requester.java new file mode 100644 index 0000000..ac06e12 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Requester.java @@ -0,0 +1,77 @@ +package xyz.sheepstar.util.http.client; + +import okhttp3.OkHttpClient; +import org.slf4j.Logger; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.log.LogManager; + +import java.util.concurrent.TimeUnit; + +public class Requester { + + private static final Logger LOG = LogManager.getLog(Requester.class); + private static final String USER_AGENT = "SheepstarBot"; + private final SheepstarImpl api; + + private final OkHttpClient client = new OkHttpClient.Builder().connectTimeout(0, TimeUnit.SECONDS).readTimeout(0, TimeUnit.SECONDS).build(); + + /** + * Constructor of the {@link Requester} + * + * @param api The {@link SheepstarImpl} instance + */ + public Requester(SheepstarImpl api) { + this.api = api; + } + + /** + * Send a request to the API + * + * @param request The request to send + * @param <T> The type of the response + */ + public <T> void request(Request<?> request) { + okhttp3.Request.Builder builder = new okhttp3.Request.Builder(); + builder.url(api.getConfig().getApiUrl() + "/" + request.getRoute().getCompiledRoute()); + + builder.method(request.getRoute().getEndpoint().getMethod().toString(), request.convertToBody()); + + if (!api.getConfig().getApiKey().isEmpty()) + builder.addHeader("Authorization", "Bearer " + api.getConfig().getApiKey()); + + builder.addHeader("User-Agent", USER_AGENT); + + okhttp3.Request build = builder.build(); + + try { + int attempt = 0; + okhttp3.Response lastResponse; + + do { + lastResponse = client.newCall(build).execute(); + + if (lastResponse.code() == 200) + break; + + attempt++; + + try { + Thread.sleep(50L * attempt); + } catch (Exception ignored) { + } + } while (attempt < 3 && lastResponse.code() != 200); + + if (lastResponse.code() != 200) { + request.handleError(lastResponse); + lastResponse.close(); + return; + } + + request.handleSuccess(lastResponse); + } catch (Exception e) { + request.handleError(null); + LOG.error("Error while requesting: {}", e.getMessage()); + } + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Response.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Response.java new file mode 100644 index 0000000..a112ddb --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Response.java @@ -0,0 +1,70 @@ +package xyz.sheepstar.util.http.client; + +import net.dv8tion.jda.api.utils.data.DataArray; +import net.dv8tion.jda.api.utils.data.DataObject; +import okhttp3.ResponseBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class Response { + + private static final Logger LOG = LoggerFactory.getLogger(Response.class); + + private int code = 500; + + private String body = "{}"; + + /** + * Constructor of the {@link Response} + * + * @param response The {@link okhttp3.Response} + */ + public Response(okhttp3.Response response) { + if (response == null) return; + code = response.code(); + try { + ResponseBody body = response.body(); + this.body = body.string(); + body.close(); + } catch (Exception e) { + LOG.error("Could not get response body: {}", e.getMessage()); + } + response.close(); + } + + /** + * Gets the {@link DataObject} + * + * @return the {@link DataObject} + */ + public DataObject getData() { + return DataObject.fromJson(body); + } + + /** + * Gets the {@link DataArray} + * + * @return The {@link DataArray} + */ + public DataArray getArray() { + return DataArray.fromJson(body); + } + + /** + * Gets the HTTP status code + * + * @return the HTTP status code + */ + public int getCode() { + return code; + } + + /** + * Gets the body of the response + * + * @return the body of the response + */ + public String getBody() { + return body; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RestAction.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RestAction.java new file mode 100644 index 0000000..ed981e9 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/RestAction.java @@ -0,0 +1,12 @@ +package xyz.sheepstar.util.http.client; + +public interface RestAction<T> { + + /** + * Completes the action + * + * @return the result of the action + */ + T complete(); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Route.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Route.java new file mode 100644 index 0000000..cac8797 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/Route.java @@ -0,0 +1,94 @@ +package xyz.sheepstar.util.http.client; + +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.HashMap; +import java.util.Map; + +public class Route { + + private final HashMap<String, String> compiled_patterns = new HashMap<>(); + private final Endpoint endpoint; + private final HashMap<String, Object> query_params = new HashMap<>(); + + /** + * Constructor of the {@link Route} + * + * @param endpoint The endpoint of the route + */ + public Route(Endpoint endpoint) { + this.endpoint = endpoint; + } + + + /** + * Adds a pattern to the route + * + * @param key The key of the pattern + * @param value The value of the pattern + * @return The route + */ + public Route compilePattern(String key, String value) { + compiled_patterns.put(key, value); + return this; + } + + /** + * Adds a query parameter to the route + * + * @param key The key of the query parameter + * @param value The value of the query parameter + * @return The route + */ + public Route addQueryParam(String key, Object value) { + query_params.put(key, value); + return this; + } + + /** + * Returns the endpoint of the route + * + * @return the endpoint + */ + public Endpoint getEndpoint() { + return endpoint; + } + + /** + * Returns the compiled pattern of the route + * + * @return the compiled pattern + */ + public String getCompiledRoute() { + String compiled_route = endpoint.getPath(); + try { + for (Map.Entry<String, String> entry : compiled_patterns.entrySet()) { + compiled_route = compiled_route.replace(String.format("{%s}", entry.getKey()), + URLEncoder.encode(entry.getValue(), "UTF-8")); + } + } catch (UnsupportedEncodingException ignored) { + } + + compiled_route += "/" + compileQuery(); + + return compiled_route; + } + + /** + * Get the compiled query of the route + * + * @return the compiled query + */ + private String compileQuery() { + StringBuilder query = new StringBuilder(); + try { + for (Map.Entry<String, Object> entry : query_params.entrySet()) { + query.append(String.format("%s%s=%s", (query.length() == 0) ? "?" : "&", entry.getKey(), + URLEncoder.encode(entry.getValue().toString(), "UTF-8"))); + } + } catch (UnsupportedEncodingException ignored) { + } + return query.toString(); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/FindArticleInfoImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/FindArticleInfoImpl.java new file mode 100644 index 0000000..6cfc6a8 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/FindArticleInfoImpl.java @@ -0,0 +1,40 @@ +package xyz.sheepstar.util.http.client.actions.internal.article; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.ErrorResponse; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.entities.Article; +import xyz.sheepstar.util.http.client.entities.internal.ArticleImpl; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +public class FindArticleInfoImpl extends RestActionImpl<Article> { + + private final String moduleName; + private final String articleId; + + /** + * Constructor of the {@link FindArticleInfoImpl} + * + * @param api the api of the bot + */ + public FindArticleInfoImpl(SheepstarImpl api, String moduleName, String articleId) { + super(api); + this.moduleName = moduleName; + this.articleId = articleId; + } + + @Override + protected Route finalizeRoute() { + return new Route(Endpoint.Article.FIND_ARTICLE) + .compilePattern("module_name", moduleName) + .compilePattern("article_id", articleId); + } + + @Override + public Article handle(Response response) { + if (response instanceof ErrorResponse) return null; + return ArticleImpl.from(response.getData()); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticleInfoActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticleInfoActionImpl.java new file mode 100644 index 0000000..e2fb101 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticleInfoActionImpl.java @@ -0,0 +1,37 @@ +package xyz.sheepstar.util.http.client.actions.internal.article; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.ErrorResponse; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.entities.Article; +import xyz.sheepstar.util.http.client.entities.internal.ArticleImpl; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +public class GetArticleInfoActionImpl extends RestActionImpl<Article> { + + private final String articleId; + + /** + * Constructor of the {@link RestActionImpl} + * + * @param api the api of the bot + */ + public GetArticleInfoActionImpl(SheepstarImpl api, String articleId) { + super(api); + this.articleId = articleId; + } + + @Override + protected Route finalizeRoute() { + return new Route(Endpoint.Article.GET_ARTICLE) + .compilePattern("article_id", articleId); + } + + @Override + public Article handle(Response response) { + if (response instanceof ErrorResponse) return null; + return ArticleImpl.from(response.getData()); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticlesActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticlesActionImpl.java new file mode 100644 index 0000000..f1fb6b2 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/article/GetArticlesActionImpl.java @@ -0,0 +1,48 @@ +package xyz.sheepstar.util.http.client.actions.internal.article; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.ErrorResponse; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.entities.Article; +import xyz.sheepstar.util.http.client.entities.internal.ArticleImpl; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class GetArticlesActionImpl extends RestActionImpl<List<Article>> { + + private final String moduleName; + + /** + * Constructor of the {@link RestActionImpl} + * + * @param api the api of the bot + * @param moduleName The name of the module + */ + public GetArticlesActionImpl(SheepstarImpl api, String moduleName) { + super(api); + this.moduleName = moduleName; + } + + @Override + protected Route finalizeRoute() { + return new Route(Endpoint.Article.LIST_ARTICLES) + .compilePattern("module_name", moduleName); + } + + @Override + public List<Article> handle(Response response) { + if (response instanceof ErrorResponse) return null; + List<Article> items = new ArrayList<>(); + + for (Object o : response.getArray()) { + items.add(ArticleImpl.from((HashMap<String, Object>) o)); + } + + return items; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/GiftInfoActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/GiftInfoActionImpl.java new file mode 100644 index 0000000..51fcabc --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/GiftInfoActionImpl.java @@ -0,0 +1,44 @@ +package xyz.sheepstar.util.http.client.actions.internal.gift; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.ErrorResponse; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.entities.Gift; +import xyz.sheepstar.util.http.client.entities.internal.GiftImpl; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +import java.text.ParseException; + +public class GiftInfoActionImpl extends RestActionImpl<Gift> { + + private final String giftId; + + /** + * Constructor of the {@link RestActionImpl} + * + * @param api the api of the bot + * @param giftId The id of the gift + */ + public GiftInfoActionImpl(SheepstarImpl api, String giftId) { + super(api); + this.giftId = giftId; + } + + @Override + protected Route finalizeRoute() { + return new Route(Endpoint.Gift.GET_GIFT) + .compilePattern("gift_id", giftId); + } + + @Override + public Gift handle(Response response) { + if (response instanceof ErrorResponse) return null; + try { + return GiftImpl.from(response.getData()); + } catch (ParseException ignored) { + } + return null; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/RedeemGiftActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/RedeemGiftActionImpl.java new file mode 100644 index 0000000..3fc50ab --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/gift/RedeemGiftActionImpl.java @@ -0,0 +1,42 @@ +package xyz.sheepstar.util.http.client.actions.internal.gift; + +import net.dv8tion.jda.api.utils.data.DataObject; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +public class RedeemGiftActionImpl extends RestActionImpl<Integer> { + + private final String giftId; + private final String guildId; + + /** + * Constructor of the {@link RedeemGiftActionImpl} + * + * @param api The api of the bot + * @param giftId The id of the gift + * @param guildId The id of the guild + */ + public RedeemGiftActionImpl(SheepstarImpl api, String giftId, String guildId) { + super(api); + this.giftId = giftId; + this.guildId = guildId; + } + + @Override + protected DataObject finalizeBody() { + return DataObject.empty().put("giftID", giftId).put("guildID", guildId); + } + + @Override + protected Route finalizeRoute() { + return new Route(Endpoint.Gift.REDEEM_CODE); + } + + @Override + public Integer handle(Response response) { + return response.getCode(); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ActivateArticleActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ActivateArticleActionImpl.java new file mode 100644 index 0000000..589e5e1 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ActivateArticleActionImpl.java @@ -0,0 +1,40 @@ +package xyz.sheepstar.util.http.client.actions.internal.shop; + +import net.dv8tion.jda.api.utils.data.DataObject; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +public class ActivateArticleActionImpl extends RestActionImpl<Integer> { + + private final String articleId; + private final String guildId; + + /** + * Constructor of the {@link ActivateArticleActionImpl} + * + * @param api the api of the bot + */ + public ActivateArticleActionImpl(SheepstarImpl api, String articleId, String guildId) { + super(api); + this.articleId = articleId; + this.guildId = guildId; + } + + @Override + protected DataObject finalizeBody() { + return DataObject.empty().put("articleID", articleId).put("guildID", guildId); + } + + @Override + protected Route finalizeRoute() { + return new Route(Endpoint.Shop.ACTIVATE_ITEM); + } + + @Override + public Integer handle(Response response) { + return response.getCode(); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/HasArticleActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/HasArticleActionImpl.java new file mode 100644 index 0000000..a88fea8 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/HasArticleActionImpl.java @@ -0,0 +1,39 @@ +package xyz.sheepstar.util.http.client.actions.internal.shop; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.ErrorResponse; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +public class HasArticleActionImpl extends RestActionImpl<Boolean> { + + private final String articleId; + private final String guildId; + + /** + * Constructor of the {@link HasArticleActionImpl} + * + * @param api the api of the bot + */ + public HasArticleActionImpl(SheepstarImpl api, String articleID, String guildID) { + super(api); + this.articleId = articleID; + this.guildId = guildID; + } + + + @Override + protected Route finalizeRoute() { + return new Route(Endpoint.Shop.OWNS_ITEM) + .addQueryParam("articleID", articleId) + .addQueryParam("guildID", guildId); + } + + @Override + public Boolean handle(Response response) { + if (response instanceof ErrorResponse) return null; + return Boolean.valueOf(response.getBody()); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ShopItemsActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ShopItemsActionImpl.java new file mode 100644 index 0000000..f740420 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/actions/internal/shop/ShopItemsActionImpl.java @@ -0,0 +1,70 @@ +package xyz.sheepstar.util.http.client.actions.internal.shop; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Endpoint; +import xyz.sheepstar.util.http.client.ErrorResponse; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.Route; +import xyz.sheepstar.util.http.client.entities.ShopItem; +import xyz.sheepstar.util.http.client.entities.internal.ShopItemImpl; +import xyz.sheepstar.util.http.client.internal.RestActionImpl; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ShopItemsActionImpl extends RestActionImpl<List<ShopItem>> { + + private final String guildID; + private String articleID; + + /** + * Constructor of the {@link RestActionImpl} + * + * @param api the api of the bot + * @param guildID The id of the guild + */ + public ShopItemsActionImpl(SheepstarImpl api, String articleID, String guildID) { + super(api); + this.guildID = guildID; + this.articleID = articleID; + } + + /** + * Constructor of the {@link RestActionImpl} + * + * @param api the api of the bot + * @param guildID The id of the guild + */ + public ShopItemsActionImpl(SheepstarImpl api, String guildID) { + super(api); + this.guildID = guildID; + } + + + @Override + protected Route finalizeRoute() { + Route route = new Route(Endpoint.Shop.GET_ITEMS); + + if (articleID != null) + route.addQueryParam("articleID", articleID); + + return route.addQueryParam("guildID", guildID); + } + + @Override + public List<ShopItem> handle(Response response) { + if (response instanceof ErrorResponse) return null; + List<ShopItem> items = new ArrayList<>(); + + for (Object o : response.getArray()) { + try { + items.add(ShopItemImpl.from((HashMap<String, Object>) o)); + } catch (ParseException ignored) { + } + } + + return items; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Article.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Article.java new file mode 100644 index 0000000..7748c4e --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Article.java @@ -0,0 +1,70 @@ +package xyz.sheepstar.util.http.client.entities; + +import java.util.Map; + +public interface Article { + + /** + * Gets the article id + * + * @return the article id + */ + int getID(); + + /** + * Gets the module name + * + * @return the module name + */ + String getModuleName(); + + /** + * Gets the article id + * + * @return the article id + */ + String getArticleId(); + + /** + * Gets the article name + * + * @return the article name + */ + String getArticleName(); + + /** + * Gets the image id + * + * @return the image id + */ + String getImageId(); + + /** + * Gets the article description + * + * @return the article description + */ + String getArticleDescription(); + + /** + * Gets the article extras + * + * @return the article extras + */ + Map<String, Object> getArticleExtras(); + + /** + * Gets the article price + * + * @return the article price + */ + int getArticlePrice(); + + /** + * Gets the max own count of the article + * + * @return the max own count of the article + */ + int getMaxOwnCount(); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Gift.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Gift.java new file mode 100644 index 0000000..aea32e9 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/Gift.java @@ -0,0 +1,35 @@ +package xyz.sheepstar.util.http.client.entities; + +import java.util.Date; + +public interface Gift { + + /** + * Gets the id of the gift + * + * @return the id of the gift + */ + String getId(); + + /** + * Gets the article id of the gift + * + * @return the article id of the gift + */ + String getArticleId(); + + /** + * Gets the expiry date of the gift + * + * @return the expiry date of the gift + */ + Date getExpiryDate(); + + /** + * Gets the item expiry date of the gift + * + * @return the item expiry date of the gift + */ + Date getItemExpiryDate(); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/ShopItem.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/ShopItem.java new file mode 100644 index 0000000..7acc75c --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/ShopItem.java @@ -0,0 +1,36 @@ +package xyz.sheepstar.util.http.client.entities; + + +import java.util.Date; + +public interface ShopItem { + + /** + * Gets the id of the shop item + * + * @return the id of the shop item + */ + int getId(); + + /** + * Gets the expiry date of the shop item + * + * @return the expiry date of the shop item + */ + Date getExpiryDate(); + + /** + * Gets the article id of the shop item + * + * @return the article id of the shop item + */ + String getArticleId(); + + /** + * Gets the guild if of the shop item + * + * @return the guild if of the shop item + */ + String getGuildId(); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ArticleImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ArticleImpl.java new file mode 100644 index 0000000..b5f2fdd --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ArticleImpl.java @@ -0,0 +1,106 @@ +package xyz.sheepstar.util.http.client.entities.internal; + +import net.dv8tion.jda.api.utils.data.DataObject; +import xyz.sheepstar.util.http.client.entities.Article; + +import java.util.Map; + +public class ArticleImpl implements Article { + + + private final int id; + private final String moduleName; + private final String articleId; + private final String articleName; + private final String imageId; + private final String articleDescription; + private final Map<String, Object> articleExtras; + private final int articlePrice; + private final int maxOwnCount; + + public ArticleImpl(int id, String moduleName, String articleId, String articleName, String imageId, String articleDescription, + Map<String, Object> articleExtras, int articlePrice, int maxOwnCount) { + this.id = id; + this.moduleName = moduleName; + this.articleId = articleId; + this.articleName = articleName; + this.imageId = imageId; + this.articleDescription = articleDescription; + this.articleExtras = articleExtras; + this.articlePrice = articlePrice; + this.maxOwnCount = maxOwnCount; + } + + public static ArticleImpl from(DataObject data) { + return new ArticleImpl( + data.getInt("id"), + data.getString("moduleName"), + data.getString("articleID"), + data.getString("articleName"), + !data.isNull("imageID") ? data.getString("imageID") : null, + data.getString("articleDescription"), + !data.isNull("articleExtras") ? data.getObject("articleExtras").toMap() : null, + data.getInt("articlePrice"), + data.getInt("maxOwnCount") + ); + } + + public static ArticleImpl from(Map<String, Object> data) { + return new ArticleImpl( + (int) data.get("id"), + (String) data.get("moduleName"), + (String) data.get("articleID"), + (String) data.get("articleName"), + (String) data.get("imageID"), + (String) data.get("articleDescription"), + (Map<String, Object>) data.get("articleExtras"), + (int) data.get("articlePrice"), + (int) data.get("maxOwnCount") + ); + } + + @Override + public int getID() { + return id; + } + + @Override + public String getModuleName() { + return moduleName; + } + + @Override + public String getArticleId() { + return articleId; + } + + @Override + public String getArticleName() { + return articleName; + } + + @Override + public String getImageId() { + return imageId; + } + + @Override + public String getArticleDescription() { + return articleDescription; + } + + @Override + public Map<String, Object> getArticleExtras() { + return articleExtras; + } + + @Override + public int getArticlePrice() { + return articlePrice; + } + + @Override + public int getMaxOwnCount() { + return maxOwnCount; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/GiftImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/GiftImpl.java new file mode 100644 index 0000000..eaf77df --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/GiftImpl.java @@ -0,0 +1,53 @@ +package xyz.sheepstar.util.http.client.entities.internal; + +import net.dv8tion.jda.api.utils.data.DataObject; +import xyz.sheepstar.util.http.client.entities.Gift; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class GiftImpl implements Gift { + + private final String id; + private final String articleId; + private final Date expiryDate; + private final Date itemExpiryDate; + + public GiftImpl(String id, String articleId, Date expiryDate, Date itemExpiryDate) { + this.id = id; + this.articleId = articleId; + this.expiryDate = expiryDate; + this.itemExpiryDate = itemExpiryDate; + } + + public static GiftImpl from(DataObject data) throws ParseException { + return new GiftImpl( + data.getString("giftID"), + data.getString("articleID"), + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(data.getString("expiry_date")), + new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(data.getString("item_expiry_date")) + ); + } + + @Override + public String getId() { + return id; + } + + @Override + public String getArticleId() { + return articleId; + } + + @Override + public Date getExpiryDate() { + return expiryDate; + } + + @Override + public Date getItemExpiryDate() { + return itemExpiryDate; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ShopItemImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ShopItemImpl.java new file mode 100644 index 0000000..dbbe942 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/entities/internal/ShopItemImpl.java @@ -0,0 +1,63 @@ +package xyz.sheepstar.util.http.client.entities.internal; + +import xyz.sheepstar.util.http.client.entities.ShopItem; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; + +public class ShopItemImpl implements ShopItem { + + private final int id; + private final Date expiryDate; + private final String articleId; + private final String guildId; + + /** + * Constructor of the {@link ShopItemImpl} + * + * @param id The id of the shop item + * @param expiryDate The expiry date of the shop item + * @param articleId The article id of the shop item + * @param guildId The guild id of the shop item + */ + public ShopItemImpl(int id, Date expiryDate, String articleId, String guildId) { + this.id = id; + this.expiryDate = expiryDate; + this.articleId = articleId; + this.guildId = guildId; + } + + /** + * Parses a {@link ShopItem} from a {@link HashMap} + * + * @param map The {@link HashMap} to parse + * @return The parsed {@link ShopItem} + * @throws ParseException If the date could not be parsed + */ + public static ShopItemImpl from(HashMap<String, Object> map) throws ParseException { + return new ShopItemImpl((int) map.get("id"), new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse((String) map.get("expiry_date")), + map.get("articleID").toString(), map.get("guildID").toString()); + } + + @Override + public int getId() { + return id; + } + + @Override + public Date getExpiryDate() { + return expiryDate; + } + + @Override + public String getArticleId() { + return articleId; + } + + @Override + public String getGuildId() { + return guildId; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/internal/RestActionImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/internal/RestActionImpl.java new file mode 100644 index 0000000..179f524 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/internal/RestActionImpl.java @@ -0,0 +1,69 @@ +package xyz.sheepstar.util.http.client.internal; + +import net.dv8tion.jda.api.utils.data.DataObject; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.Request; +import xyz.sheepstar.util.http.client.Response; +import xyz.sheepstar.util.http.client.RestAction; +import xyz.sheepstar.util.http.client.Route; + +import java.util.concurrent.CompletableFuture; + +public class RestActionImpl<T> implements RestAction<T> { + + private final SheepstarImpl api; + + /** + * Constructor of the {@link RestActionImpl} + * + * @param api the api of the bot + */ + public RestActionImpl(SheepstarImpl api) { + this.api = api; + } + + @Override + public T complete() { + return submit().join(); + } + + /** + * Submits the request and returns a future that will be completed when the request is complete + * + * @return a future that will be completed when the request is complete + */ + protected CompletableFuture<T> submit() { + CompletableFuture<T> future = new CompletableFuture<>(); + api.getRequester().request(new Request<>(finalizeRoute(), finalizeBody(), future, this)); + return future; + } + + /** + * Returns the body of the request + * + * @return the body of the request + */ + protected DataObject finalizeBody() { + return null; + } + + /** + * Returns the route of the request + * + * @return the route of the request + */ + protected Route finalizeRoute() { + return null; + } + + /** + * Handles the response of the request + * + * @param response the response of the request + * @return the response of the request + */ + public T handle(Response response) { + return null; + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ArticleObject.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ArticleObject.java new file mode 100644 index 0000000..5e6f949 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ArticleObject.java @@ -0,0 +1,28 @@ +package xyz.sheepstar.util.http.client.objects; + +import xyz.sheepstar.util.http.client.RestAction; +import xyz.sheepstar.util.http.client.entities.Article; + +import java.util.List; + +public interface ArticleObject { + + /** + * Gets the information about an article + * + * @param articleId The id of the article + * @return the article object + */ + RestAction<Article> getArticle(String articleId); + + /** + * Gets the information about an article + * + * @param moduleName The name of the module + * @param articleId The id of the article + * @return the article object + */ + RestAction<Article> findArticle(String moduleName, String articleId); + + RestAction<List<Article>> getArticles(String moduleName); +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/GiftObject.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/GiftObject.java new file mode 100644 index 0000000..c293be2 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/GiftObject.java @@ -0,0 +1,26 @@ +package xyz.sheepstar.util.http.client.objects; + +import net.dv8tion.jda.api.entities.Guild; +import xyz.sheepstar.util.http.client.RestAction; +import xyz.sheepstar.util.http.client.entities.Gift; + +public interface GiftObject { + + /** + * Redeems the provided gift code + * + * @param code The code to redeem + * @param guild The guild to redeem the code in + * @return the status code + */ + RestAction<Integer> redeemGift(String code, Guild guild); + + /** + * Gets the gift object for the provided code + * + * @param code The code to get the gift object for + * @return the gift object + */ + RestAction<Gift> getInfo(String code); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ShopObject.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ShopObject.java new file mode 100644 index 0000000..6ae9acc --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/ShopObject.java @@ -0,0 +1,54 @@ +package xyz.sheepstar.util.http.client.objects; + +import net.dv8tion.jda.api.entities.Guild; +import xyz.sheepstar.util.http.client.RestAction; +import xyz.sheepstar.util.http.client.entities.ShopItem; + +import java.util.List; + +public interface ShopObject { + + + /** + * Checks if the provided guild has the provided item + * + * @param articleId The id of the item + * @param guild The guild to check + * @return <code>true</code> if the guild has the item, otherwise <code>false</code> + */ + RestAction<Boolean> hasItem(String articleId, Guild guild); + + /** + * Checks if the provided guild has the provided item + * + * @param guild The guild to check + * @return <code>true</code> if the guild has the item, otherwise <code>false</code> + */ + RestAction<Boolean> hasPremium(Guild guild); + + /** + * Gets all items from the provided guild + * + * @param guild The guild to get the items from + * @return a list of all items + */ + RestAction<List<ShopItem>> getItems(Guild guild); + + /** + * Gets all items from the provided guild + * + * @param guild The guild to get the items from + * @return a list of all items + */ + RestAction<List<ShopItem>> getItems(String articleId, Guild guild); + + /** + * Activates the provided item + * + * @param articleId The id of the item + * @param guild The guild to activate the item in + * @return the response code + */ + RestAction<Integer> activateItem(String articleId, Guild guild); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ArticleObjectImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ArticleObjectImpl.java new file mode 100644 index 0000000..5357142 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ArticleObjectImpl.java @@ -0,0 +1,41 @@ +package xyz.sheepstar.util.http.client.objects.internal; + +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.RestAction; +import xyz.sheepstar.util.http.client.actions.internal.article.FindArticleInfoImpl; +import xyz.sheepstar.util.http.client.actions.internal.article.GetArticleInfoActionImpl; +import xyz.sheepstar.util.http.client.actions.internal.article.GetArticlesActionImpl; +import xyz.sheepstar.util.http.client.entities.Article; +import xyz.sheepstar.util.http.client.objects.ArticleObject; + +import java.util.List; + +public class ArticleObjectImpl implements ArticleObject { + + private final SheepstarImpl api; + + /** + * Constructor of the {@link ShopObjectImpl} + * + * @param api The {@link SheepstarImpl} instance + */ + public ArticleObjectImpl(SheepstarImpl api) { + this.api = api; + } + + @Override + public RestAction<Article> getArticle(String articleId) { + return new GetArticleInfoActionImpl(api, articleId); + } + + @Override + public RestAction<Article> findArticle(String moduleName, String articleId) { + return new FindArticleInfoImpl(api, moduleName, articleId); + } + + @Override + public RestAction<List<Article>> getArticles(String moduleName) { + return new GetArticlesActionImpl(api, moduleName); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/GiftObjectImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/GiftObjectImpl.java new file mode 100644 index 0000000..8747583 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/GiftObjectImpl.java @@ -0,0 +1,34 @@ +package xyz.sheepstar.util.http.client.objects.internal; + +import net.dv8tion.jda.api.entities.Guild; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.RestAction; +import xyz.sheepstar.util.http.client.actions.internal.gift.GiftInfoActionImpl; +import xyz.sheepstar.util.http.client.actions.internal.gift.RedeemGiftActionImpl; +import xyz.sheepstar.util.http.client.entities.Gift; +import xyz.sheepstar.util.http.client.objects.GiftObject; + +public class GiftObjectImpl implements GiftObject { + + private final SheepstarImpl api; + + /** + * Constructor of the {@link GiftObjectImpl} + * + * @param api The current sheepstar instance + */ + public GiftObjectImpl(SheepstarImpl api) { + this.api = api; + } + + @Override + public RestAction<Integer> redeemGift(String code, Guild guild) { + return new RedeemGiftActionImpl(api, code, guild.getId()); + } + + @Override + public RestAction<Gift> getInfo(String code) { + return new GiftInfoActionImpl(api, code); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ShopObjectImpl.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ShopObjectImpl.java new file mode 100644 index 0000000..c6c23ea --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/client/objects/internal/ShopObjectImpl.java @@ -0,0 +1,51 @@ +package xyz.sheepstar.util.http.client.objects.internal; + +import net.dv8tion.jda.api.entities.Guild; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.http.client.RestAction; +import xyz.sheepstar.util.http.client.actions.internal.shop.ActivateArticleActionImpl; +import xyz.sheepstar.util.http.client.actions.internal.shop.HasArticleActionImpl; +import xyz.sheepstar.util.http.client.actions.internal.shop.ShopItemsActionImpl; +import xyz.sheepstar.util.http.client.entities.ShopItem; +import xyz.sheepstar.util.http.client.objects.ShopObject; + +import java.util.List; + +public class ShopObjectImpl implements ShopObject { + + private final SheepstarImpl api; + + /** + * Constructor of the {@link ShopObjectImpl} + * + * @param api The {@link SheepstarImpl} instance + */ + public ShopObjectImpl(SheepstarImpl api) { + this.api = api; + } + + @Override + public RestAction<Boolean> hasItem(String articleId, Guild guild) { + return new HasArticleActionImpl(api, articleId, guild.getId()); + } + + @Override + public RestAction<Boolean> hasPremium(Guild guild) { + return new HasArticleActionImpl(api, "1", guild.getId()); + } + + @Override + public RestAction<List<ShopItem>> getItems(Guild guild) { + return new ShopItemsActionImpl(api, guild.getId()); + } + + @Override + public RestAction<List<ShopItem>> getItems(String moduleName, Guild guild) { + return new ShopItemsActionImpl(api, moduleName, guild.getId()); + } + + @Override + public RestAction<Integer> activateItem(String articleId, Guild guild) { + return new ActivateArticleActionImpl(api, articleId, guild.getId()); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/server/WebServer.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/server/WebServer.java new file mode 100644 index 0000000..62d46e0 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/http/server/WebServer.java @@ -0,0 +1,22 @@ +package xyz.sheepstar.util.http.server; + +import com.sun.net.httpserver.HttpServer; + +import java.io.IOException; +import java.net.InetSocketAddress; + +public class WebServer extends Thread { + + /** + * Starts the webserver + */ + @Override + public void run() { + try { + HttpServer server = HttpServer.create(new InetSocketAddress(7279), 0); + server.setExecutor(null); + server.start(); + } catch (IOException ignored) { + } + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/CacheManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/CacheManager.java new file mode 100644 index 0000000..9c5e377 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/CacheManager.java @@ -0,0 +1,74 @@ +package xyz.sheepstar.util.internal.manager; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.log.LogManager; + +import java.io.File; +import java.io.InputStream; + +public class CacheManager { + + private static final Logger LOG = LogManager.getLog(CacheManager.class); + private static final File CACHE_FOLDER = new File("./cache/"); + + private final SheepstarImpl api; + + /** + * Constructor of the {@link CacheManager} + * + * @param api The current sheepstar api object + */ + public CacheManager(SheepstarImpl api) { + this.api = api; + } + + /** + * Downloads an asset directly to the cache + * + * @param url The url you want to get the asset from + * @param fileName The name of the file + */ + public void downloadAsset(String url, String fileName) { + LOG.info("Downloading asset file {}", fileName); + try { + InputStream stream = new OkHttpClient().newCall(new Request.Builder().url(url) + .addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11") + .build()).execute().body().byteStream(); + FileUtils.copyInputStreamToFile(stream, new File(CACHE_FOLDER.getPath() + "/" + fileName)); + LOG.info("Asset file {} got successfully downloaded", fileName); + } catch (Exception e) { + LOG.error("Could not download the asset file {} to the cache: {}", fileName, e.getMessage()); + } + } + + /** + * Gets a file from the cache + * + * @param fileName The file you want to get + * @return the cached file + */ + public File getFile(String fileName) { + return new File(CACHE_FOLDER.getPath() + "/" + fileName); + } + + /** + * Initializes the cache of the bot. + * <p> + * Current cached objects: + * <ol> + * <li>avatar.png</li> + * </ol> + */ + public void loadDefaultCacheElements() { + if (!(CACHE_FOLDER.exists() && CACHE_FOLDER.isDirectory())) { + if (CACHE_FOLDER.mkdir()) LOG.info("Successfully created the cache folder"); + } + + downloadAsset(api.getJDA().getSelfUser().getAvatarUrl(), "avatar.png"); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ConfigurationManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ConfigurationManager.java new file mode 100644 index 0000000..06a4e93 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ConfigurationManager.java @@ -0,0 +1,90 @@ +package xyz.sheepstar.util.internal.manager; + +import com.fasterxml.jackson.databind.JsonNode; +import net.dv8tion.jda.api.entities.Activity; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.configuration.*; +import xyz.sheepstar.util.configuration.entity.SheepstarActivity; +import xyz.sheepstar.util.configuration.entity.SheepstarPool; +import xyz.sheepstar.util.mapper.JSONContent; + +import java.io.File; +import java.util.ArrayList; + +public class ConfigurationManager { + + private final JSONContent configFile; + private SheepstarConfiguration configuration; + + /** + * Constructor of the {@link ConfigurationManager} + * + * @param api The current sheepstar api instance + * @param configFile The configuration file + */ + public ConfigurationManager(SheepstarImpl api, File configFile) { + this.configFile = new JSONContent(configFile); + + try { + updateConfiguration(); + } catch (Exception e) { + api.shutdown("The provided configuration file is invalid"); + } + } + + /** + * Gets a json node by path + * + * @param path The path you want to get + * @return the json node created by the configuration file + */ + private JsonNode get(String path) { + return configFile.getPath(path).getCurrentJsonNode(); + } + + /** + * Updates the local sheepstar configuration + */ + public void updateConfiguration() { + DatabaseConfiguration databaseConfiguration = new DatabaseConfiguration(get("mysql.hostname").asText(), get("mysql.username").asText(), + get("mysql.password").asText(), get("mysql.database").asText()); + + CommandConfiguration commandConfiguration = new CommandConfiguration(get("commands.enable_ping_feature").asBoolean(), + get("commands.enable_prefix_feature").asBoolean(), get("commands.enable_slash_feature").asBoolean(), get("commands.debug_guild").asText()); + + SupporterPermissionConfiguration supporterPermissionConfiguration = new SupporterPermissionConfiguration( + get("permissions.SUPPORTER.guildID").asText(), get("permissions.SUPPORTER.roleID").asText()); + + String[] botOwner = new String[get("permissions.BOT_OWNER").size()]; + + for (int i = 0; i < get("permissions.BOT_OWNER").size(); i++) + botOwner[i] = get("permissions.BOT_OWNER").get(i).asText(); + + PermissionConfiguration permissionConfiguration = new PermissionConfiguration(botOwner, supporterPermissionConfiguration); + + ArrayList<SheepstarActivity> activities = new ArrayList<>(); + + for (int i = 0; i < get("activities").size(); i++) { + activities.add(new SheepstarActivity(Activity.ActivityType.valueOf(get("activities").get(i).get("type").asText()), + get("activities").get(i).get("name").asText())); + } + + ArrayList<SheepstarPool> pools = new ArrayList<>(); + + for (int i = 0; i < get("pools").size(); i++) { + pools.add(new SheepstarPool(get("pools").get(i).get("name").asText(), get("pools").get(i).get("cores").asInt())); + } + + configuration = new SheepstarConfiguration(get("token").asText(), get("api_url").asText(), get("api_key").asText(), + get("moduleDirectory").asText(), databaseConfiguration, commandConfiguration, permissionConfiguration, activities, pools); + } + + /** + * Gets the sheepstar configuration + * + * @return the sheepstar configuration + */ + public SheepstarConfiguration getConfiguration() { + return configuration; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ListenerManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ListenerManager.java new file mode 100644 index 0000000..f1d43a7 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/ListenerManager.java @@ -0,0 +1,235 @@ +package xyz.sheepstar.util.internal.manager; + +import com.google.common.base.CaseFormat; +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 org.slf4j.Logger; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.bot.command.GuildCommand; +import xyz.sheepstar.util.bot.command.annotations.CommandMeta; +import xyz.sheepstar.util.bot.command.general.GeneralGuildCommand; +import xyz.sheepstar.util.bot.listener.ListenerBasics; +import xyz.sheepstar.util.bot.listener.ListenerInfo; +import xyz.sheepstar.util.bot.manager.sql.CommandMetaManager; +import xyz.sheepstar.util.log.LogManager; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ListenerManager { + + private final static Logger LOG = LogManager.getLog(ListenerManager.class); + + private final HashMap<String, ListenerInfo> classes = new HashMap<>(); + + private final ArrayList<GuildCommand> commands = new ArrayList<>(); + + private final SheepstarImpl api; + + /** + * Constructor of the {@link ListenerManager} + * + * @param api The current sheepstar instance + */ + public ListenerManager(SheepstarImpl api) { + this.api = api; + } + + /** + * Updates the internal command metadata (see {@link CommandMetaManager}) + */ + public void updateCommandMetaInternal() { + CommandMetaManager metaManager = (CommandMetaManager) api.getDatabase().getTableFactory().getTable(CommandMetaManager.class); + metaManager.clear(); + + commands.forEach((command) -> { + if (command instanceof GeneralGuildCommand) return; + CommandMeta meta = command.getClass().getAnnotation(CommandMeta.class); + + if (meta.subAliases().length != 0) { + metaManager.addCommand(getModuleName(command.getClass().getName()), meta.aliases()[0], meta.subAliases()[0], meta.description()); + } else { + metaManager.addCommand(getModuleName(command.getClass().getName()), meta.aliases()[0], meta.description()); + } + }); + } + + /** + * Gets the {@link CommandData} from the {@link GuildCommand} + * + * @param command The command you want to get the data from + * @return the {@link CommandData}, ready to integrate it + */ + public CommandData getCommandData(GuildCommand command) { + CommandMeta meta = command.getClass().getAnnotation(CommandMeta.class); + + String descriptionPrefix = command instanceof GeneralGuildCommand ? "(System)️ " + : "(" + CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, getModuleName(command.getClass().getName())) + ") "; + + CommandData data = new CommandData(meta.aliases()[0], descriptionPrefix + meta.description()); + + if (meta.subAliases().length != 0) { + data.addSubcommands(new SubcommandData(meta.subAliases()[0], descriptionPrefix + meta.description()) + .addOptions(command.getSyntaxElements())); + } else data.addOptions(command.getSyntaxElements()); + + return data; + } + + /** + * Rewrites all commands into discord {@link CommandData} objects + * + * @return a full list of command data + */ + public ArrayList<CommandData> rewriteCommandsToData() { + ArrayList<CommandData> dataList = new ArrayList<>(); + + commands.forEach(command -> { + CommandData data = rewriteOptionData(getCommandData(command)); + boolean exists = false; + for (int i = 0; i < dataList.size(); i++) { + if (data.getName().equals(dataList.get(i).getName())) { + dataList.set(i, data.addSubcommands(dataList.get(i).getSubcommands())); + exists = true; + break; + } + } + if (!exists) dataList.add(data); + }); + + return dataList; + } + + /** + * Rewrites the option data of a command data + * + * @param data The current command data + * @return the new command data with replaced option data + */ + private CommandData rewriteOptionData(CommandData data) { + CommandData newCommand = new CommandData(data.getName(), data.getDescription()); + + List<SubcommandData> subcommands = data.getSubcommands(); + + for (int i = 0; i < subcommands.size(); i++) { + SubcommandData subcommandData = subcommands.get(i); + SubcommandData newSubCommand = new SubcommandData(subcommandData.getName(), subcommandData.getDescription()); + + subcommandData.getOptions().forEach(option -> + newSubCommand.addOptions(replaceOptionData(option))); + subcommands.set(i, newSubCommand); + } + + if (data.getSubcommands().size() > 0) newCommand.addSubcommands(subcommands); + + data.getOptions().forEach(option -> + newCommand.addOptions(replaceOptionData(option))); + + return newCommand; + } + + /** + * Replaces the choices of an option data + * + * @param optionData The current options + * @return the new options + */ + private OptionData replaceOptionData(OptionData optionData) { + if (optionData.getName().equals("modulename")) { + getModules().forEach(module -> optionData.addChoice(module, module)); + optionData.addChoice("main", "main"); + } + return optionData; + } + + /** + * Registers a Listener + * + * @param moduleName The name of the module + * @param listener The Listener you want to register + */ + public void registerListener(String moduleName, Object listener) { + classes.put(listener.getClass().getName(), new ListenerInfo().setModuleName(moduleName).setListener(listener)); + api.getShardManager().addEventListener(listener); + } + + /** + * Registers a command + * + * @param moduleName The name of the module + * @param command The command you want to register + */ + public void registerCommand(String moduleName, GuildCommand command) { + LOG.info("Registering command {} from module {}", command.getClass().getAnnotation(CommandMeta.class).aliases()[0], moduleName); + + registerListener(moduleName, command); + + commands.add(command); + } + + /** + * Registers a general command + * + * @param command The command you want to register + */ + public void registerGeneralCommand(GeneralGuildCommand command) { + LOG.info("Registering general command {}", command.getClass().getAnnotation(CommandMeta.class).aliases()[0]); + + registerListener(null, command); + + commands.add(command); + } + + /** + * Gets all registered classes + * + * @return all registered classes + */ + public HashMap<String, ListenerInfo> getClasses() { + return classes; + } + + /** + * Gets all registered guild commands + * + * @return all registered guild commands + */ + public ArrayList<GuildCommand> getCommands() { + return commands; + } + + /** + * Gets a module by name + * + * @param className The classname + * @return the module name + */ + public String getModuleName(String className) { + return classes.get(className).getModuleName(); + } + + /** + * Gets the command by class + * + * @param className The class you want to search + * @return The command + */ + public ListenerBasics getListener(String className) { + return (ListenerBasics) classes.get(className).getListener(); + } + + /** + * Gets the list of modules + * + * @return the list of modules + */ + public ArrayList<String> getModules() { + ArrayList<String> modules = new ArrayList<>(); + + api.getModuleManager().getActivated_modules().forEach((name, module) -> modules.add(name)); + + return modules; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/OptionManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/OptionManager.java new file mode 100644 index 0000000..b25ac94 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/internal/manager/OptionManager.java @@ -0,0 +1,99 @@ +package xyz.sheepstar.util.internal.manager; + +import org.apache.commons.cli.*; +import xyz.sheepstar.util.SheepstarImpl; + +public class OptionManager { + + private final SheepstarImpl api; + private final String[] givenArgs; + + private final Options options = new Options(); + private CommandLine commandLine; + + /** + * Constructor of the {@link OptionManager} + * + * @param api The current sheepstar instance + * @param givenArgs The given args by the user + */ + public OptionManager(SheepstarImpl api, String[] givenArgs) { + this.api = api; + this.givenArgs = givenArgs; + } + + /** + * Prepares & parses all default options + */ + public void parseDefault() { + prepareDefaultOptions(); + parseOptions(); + } + + /** + * Adds a new option + * + * @param shortName The shortened name of the option (for example h) + * @param longName The long name of the option (for example help) + * @param hasArg Does this option require an argument? + * @param required Is this option required? + * @param description The description of the option + */ + public void addOption(String shortName, String longName, boolean hasArg, boolean required, String description) { + Option currentOption = new Option(shortName, longName, hasArg, description); + currentOption.setRequired(required); + options.addOption(currentOption); + } + + /** + * Adds all default options + */ + public void prepareDefaultOptions() { + addOption("cf", "configFile", true, true, "Sheepstar configuration file"); + addOption("debug", "debugMode", false, false, "This displays all errors in the console for debugging"); + addOption("shards", "shardAmount", true, true, "The amount of shards used in the bot"); + } + + /** + * Parses all registered options to the command line + */ + private void parseOptions() { + CommandLineParser parser = new DefaultParser(); + HelpFormatter formatter = new HelpFormatter(); + try { + commandLine = parser.parse(options, givenArgs); + } catch (ParseException e) { + formatter.printHelp("Sheepstar", options); + api.shutdown(e.getMessage()); + } + } + + /** + * Gets the commandline instance + * + * @return the commandline instance + */ + public CommandLine getCommandLine() { + return commandLine; + } + + /** + * Gets the option value of a string + * + * @param name The name of the option you want to get + * @return the option value + */ + public String getOptionValue(String name) { + return commandLine.getOptionValue(name); + } + + /** + * Checks if a specific option has been provided + * + * @param name The name of the option + * @return <code>true</code> if the option has been provided, otherwise <code>false</code> + */ + public boolean hasOption(String name) { + return commandLine.hasOption(name); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/log/LogManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/log/LogManager.java new file mode 100644 index 0000000..d9f34b2 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/log/LogManager.java @@ -0,0 +1,18 @@ +package xyz.sheepstar.util.log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LogManager { + + /** + * Gets the logger by a class + * + * @param clazz The class you want the log from + * @return the logger + */ + public static Logger getLog(Class<?> clazz) { + return LoggerFactory.getLogger(clazz); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/JSONContent.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/JSONContent.java new file mode 100644 index 0000000..3115056 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/JSONContent.java @@ -0,0 +1,199 @@ +package xyz.sheepstar.util.mapper; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; +import org.slf4j.Logger; +import xyz.sheepstar.util.log.LogManager; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + + +public class JSONContent { + + private static final Logger LOG = LogManager.getLog(JSONContent.class); + + private JsonNode jsonNode; + + /** + * The basic constructor of the JSONFile created with the content in JSON + * + * @param content content in the JSON format + */ + public JSONContent(String content) { + try { + jsonNode = SheepstarMapper.getJsonMapper().readTree(content); + } catch (JsonProcessingException e) { + LOG.error(e.getMessage()); + } + } + + /** + * The basic constructor of the JSONFile created with the content in JSON + * + * @param inputStream content in the JSON format + */ + public JSONContent(InputStream inputStream) { + try { + jsonNode = SheepstarMapper.getJsonMapper().readTree(inputStream); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + } + + /** + * The basic constructor of the JSONFile created with the content in JSON + * + * @param file The file with the content in the JSON format + */ + public JSONContent(File file) { + try { + jsonNode = SheepstarMapper.getJsonMapper().readTree(file); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + } + + /** + * Gets a string from the JSON node + * + * @param path the path you want to get + * @return the string + */ + public String getString(String path) { + return jsonNode.get(path).asText(); + } + + /** + * Gets a integer from the JSON node + * + * @param path the path you want to get + * @return the integer + */ + public int getInt(String path) { + return jsonNode.get(path).asInt(); + } + + /** + * Gets a boolean from the JSON node + * + * @param path the path you want to get + * @return the boolean + */ + public boolean getBoolean(String path) { + return jsonNode.get(path).asBoolean(); + } + + /** + * Gets a double from the JSON node + * + * @param path the path you want to get + * @return the double + */ + public double getDouble(String path) { + return jsonNode.get(path).asDouble(); + } + + /** + * Gets a long from the JSON node + * + * @param path the path you want to get + * @return the long + */ + public long getLong(String path) { + return jsonNode.get(path).asLong(); + } + + /** + * Checks if a JSON node exists + * + * @param path The path you want to check + * @return a boolean that says if the JSON node exists + */ + public boolean exists(String path) { + return jsonNode.get(path) != null; + } + + /** + * Gets the array of the json content + * + * @param path The path of the array + * @return the array node + */ + public ArrayNode getArray(String path) { + try { + return SheepstarMapper.getJsonMapper().readValue(getPath(path).getCurrentString(), ArrayNode.class); + } catch (JsonProcessingException e) { + e.printStackTrace(); + return null; + } + } + + /** + * Gets a JSON node + * + * @param path The path you want to get + * @return the JSON node + */ + public JsonNode getNode(String path) { + return jsonNode.get(path); + } + + /** + * Gets another json content by path + * + * @param path The path you want to get + * @return the json content + */ + public JSONContent get(String path) { + return new JSONContent(jsonNode.get(path).toString()); + } + + /** + * Gets another json content by path + * + * @param jsonNode The node you have + * @return the json content + */ + public JSONContent get(JsonNode jsonNode) { + return new JSONContent(jsonNode.toString()); + } + + /** + * Gets an json node by path + * + * @param path The path you want to get + * @return the json content + */ + public JSONContent getPath(String path) { + JSONContent currentNode = this; + for (String current : path.split("\\.")) + currentNode = currentNode.get(current); + return currentNode; + } + + /** + * Gets the current JSON node + * + * @return the current JSON node + */ + public JsonNode getCurrentJsonNode() { + return jsonNode; + } + + /** + * Gets the current json string + * + * @return the current json string + */ + public String getCurrentString() { + return jsonNode.toString(); + } + + @Override + public String toString() { + return "JSONContent{" + "jsonNode=" + jsonNode + '}'; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/SheepstarMapper.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/SheepstarMapper.java new file mode 100644 index 0000000..fa9e81e --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/mapper/SheepstarMapper.java @@ -0,0 +1,36 @@ +package xyz.sheepstar.util.mapper; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; + +public class SheepstarMapper { + + private static final ObjectMapper yamlMapper; + private static final ObjectMapper jsonMapper; + + static { + yamlMapper = new ObjectMapper(new YAMLFactory()); + yamlMapper.findAndRegisterModules(); + jsonMapper = new ObjectMapper(new JsonFactory()); + jsonMapper.findAndRegisterModules(); + } + + /** + * Gets the JSON mapper + * + * @return the JSON mapper + */ + public static ObjectMapper getJsonMapper() { + return jsonMapper; + } + + /** + * Gets the YAML mapper + * + * @return the YAML mapper + */ + public static ObjectMapper getYamlMapper() { + return yamlMapper; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ActivatedModule.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ActivatedModule.java new file mode 100644 index 0000000..1eac368 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ActivatedModule.java @@ -0,0 +1,59 @@ +package xyz.sheepstar.util.module; + +public class ActivatedModule { + + private final String name; + private final Thread thread; + private final SheepstarModule instance; + private final Module info; + + /** + * Constructor of the {@link ActivatedModule} + * + * @param thread The thread of the module + * @param instance The instance of the sheepstar module + * @param info The module information + */ + public ActivatedModule(Thread thread, SheepstarModule instance, Module info) { + name = info.getName(); + this.thread = thread; + this.instance = instance; + this.info = info; + } + + /** + * Gets the name of the module + * + * @return the name of the module + */ + public String getName() { + return name; + } + + /** + * Gets the thread of the module + * + * @return the thread of the module + */ + public Thread getThread() { + return thread; + } + + /** + * Gets the instance of the module + * + * @return the instance of the module + */ + public SheepstarModule getInstance() { + return instance; + } + + /** + * Gets the module information + * + * @return the module information + */ + public Module getInfo() { + return info; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/Module.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/Module.java new file mode 100644 index 0000000..2b3038f --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/Module.java @@ -0,0 +1,62 @@ +package xyz.sheepstar.util.module; + +public class Module { + + private String main; + private String name; + private String author; + + /** + * Gets the main class path + * + * @return the main class path + */ + public String getMain() { + return main; + } + + /** + * Sets the main class path + * + * @param main The main class path + */ + public void setMain(String main) { + this.main = main; + } + + /** + * Gets the name of the module + * + * @return the name of the module + */ + public String getName() { + return name; + } + + /** + * Sets the name of the module + * + * @param name The name of the module + */ + public void setName(String name) { + this.name = name; + } + + /** + * Gets the author of the module + * + * @return the author of the module + */ + public String getAuthor() { + return author; + } + + /** + * Sets the author of the module + * + * @param author The author of the module + */ + public void setAuthor(String author) { + this.author = author; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ModuleManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ModuleManager.java new file mode 100644 index 0000000..5c809a7 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/ModuleManager.java @@ -0,0 +1,267 @@ +package xyz.sheepstar.util.module; + +import org.slf4j.Logger; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.event.module.ModuleLoadedEvent; +import xyz.sheepstar.util.event.module.ModuleLoadingEvent; +import xyz.sheepstar.util.log.LogManager; +import xyz.sheepstar.util.mapper.SheepstarMapper; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.HashMap; + +public class ModuleManager { + + private final ClassLoader SHEEPSTAR_CLASSLOADER = SheepstarCore.class.getClassLoader(); + private final Logger LOG = LogManager.getLog(ModuleManager.class); + private final String MODULE_FILENAME = "module.yml"; + private final String FILE_NAME = "%s/%s"; + private final HashMap<String, ActivatedModule> activated_modules = new HashMap<>(); + private final SheepstarImpl api; + private String moduleDirectory; + + /** + * The basic constructor of the module manager + * + * @param moduleDirectory The directory that contains the modules + * @param api The sheepstar instance + */ + public ModuleManager(String moduleDirectory, SheepstarImpl api) { + createDirectory(moduleDirectory); + + this.moduleDirectory = moduleDirectory; + this.api = api; + } + + /** + * Loads a module from the module directory + * + * @param moduleName The name of the module file + * @return a boolean that says if the module has been loaded successfully + */ + public boolean loadModule(String moduleName) { + if (isValidModuleFile(String.format(FILE_NAME, moduleDirectory, moduleName))) { + try { + URLClassLoader child = new URLClassLoader( + new URL[]{new File(String.format(FILE_NAME, moduleDirectory, moduleName)).toURI().toURL()}, SHEEPSTAR_CLASSLOADER + ); + + Module module = getModule(((new URL(String.format("jar:file:%s!/%s", + String.format(FILE_NAME, moduleDirectory, moduleName), MODULE_FILENAME)).openConnection()).getInputStream())); + + Class<?> startClass = Class.forName(module.getMain(), true, child); + + File dataFolder = new File(moduleDirectory + "/data/" + module.getName()); + if (!dataFolder.exists()) dataFolder.mkdir(); + + new ModuleLoadingEvent(api, module).call(); + + // Set the module values + HashMap<String, Object> moduleValues = new HashMap<>(); + + moduleValues.put("api", api); + moduleValues.put("dataFolder", dataFolder); + moduleValues.put("info", module); + moduleValues.put("moduleJar", moduleName); + + // Prepare the module + Object startInstance = prepareModule(moduleValues, startClass); + + // Start the module (in a new thread) + Thread moduleThread = runModule(startInstance, module.getName()); + + // Add the module to the list + activated_modules.put(module.getName(), new ActivatedModule(moduleThread, (SheepstarModule) startInstance, module)); + + new ModuleLoadedEvent(api, module).call(); + LOG.info("Module {} by {} has been loaded successfully", module.getName(), module.getAuthor()); + return true; + } catch (MalformedURLException e) { + LOG.error("The provided main-Class was not found in your project"); + } catch (IOException e) { + LOG.error("Could not receive the module configuration"); + } catch (Exception e) { + LOG.error("An error occurred while loading the module {}: {}", moduleName, e.getMessage()); + } + } else { + LOG.error("The provided file does not exist."); + } + return false; + } + + /** + * Prepares the provided module + * + * @param moduleValues The values you want to set in the module + * @return the start instance of the module + */ + private Object prepareModule(HashMap<String, Object> moduleValues, Class<?> startClass) throws MalformedURLException, + InstantiationException, IllegalAccessException { + + Object startInstance = startClass.newInstance(); + + // Set all module values + moduleValues.forEach((name, value) -> { + try { + Field field = startInstance.getClass().getSuperclass().getDeclaredField(name); + field.setAccessible(true); + field.set(startInstance, value); + field.setAccessible(true); + } catch (Exception e) { + LOG.error("Error while setting the {} value", name); + } + }); + + return startInstance; + } + + /** + * Runs the provided module + * + * @param startInstance The start instance of the module + * @param moduleName The name of the module you want to start + * @return the created thread + */ + private Thread runModule(Object startInstance, String moduleName) { + return createModuleThread(() -> { + try { + if (startInstance instanceof SheepstarModule) + ((SheepstarModule) startInstance).onEnable(); + } catch (Exception e) { + LOG.error("An error occurred in the start method of the module {}: {}", moduleName, e.getMessage()); + if (api.isDebugModeEnabled()) + e.printStackTrace(); + } + }, moduleName); + } + + /** + * Unloads an module + * + * @param moduleName The module you want to unload / end + * @return <code>true</code> if the module has been unloaded successfully, otherwise <code>false</code> + */ + public boolean unloadModule(String moduleName) { + try { + ActivatedModule activatedModule = activated_modules.get(moduleName); + activatedModule.getInstance().onDisable(); + activatedModule.getThread().interrupt(); + activated_modules.remove(moduleName); + } catch (Exception e) { + LOG.error("Error while unloading module {}: {}", moduleName, e.getMessage()); + return false; + } + return true; + } + + /** + * Loads all modules from the directory + */ + public void loadAllModules() { + int modules = 0; + int validModules = 0; + for (File f : new File(moduleDirectory).listFiles()) { + if (f.isFile()) { + modules++; + if (loadModule(f.getName())) validModules++; + } + + } + LOG.info("Successfully loaded " + validModules + "/" + modules + " modules."); + } + + /** + * Creates the module directory + * + * @param moduleDirectory The directory + */ + private void createDirectory(String moduleDirectory) { + new File(moduleDirectory).mkdir(); + new File(moduleDirectory + "/data").mkdir(); + } + + /** + * Checks if the directory is a valid module directory + * + * @param moduleDirectory The path of the module directory + * @return a boolean that says if the provided directory is valid + */ + private boolean isValidModuleDirectory(String moduleDirectory) { + File directory = new File(moduleDirectory); + return directory.exists() && directory.isDirectory(); + } + + /** + * Checks if the file is a valid module file + * + * @param moduleFile The path of the module file + * @return a boolean that says if the provided file is valid + */ + private boolean isValidModuleFile(String moduleFile) { + File file = new File(moduleFile); + return file.exists() && file.isFile(); + } + + /** + * Creates a module thread + * + * @param runnable The runnable which contains the module + * @param moduleName The name of the module/thread + * @return the created thread + */ + private Thread createModuleThread(Runnable runnable, String moduleName) { + Thread moduleThread = new Thread(runnable); + moduleThread.setName(moduleName); + moduleThread.start(); + return moduleThread; + } + + /** + * Gets a module by a JSON file/input + * + * @param moduleStream The stream of the JSON file + * @return the module + */ + public Module getModule(InputStream moduleStream) { + try { + return SheepstarMapper.getYamlMapper().readValue(moduleStream, Module.class); + } catch (IOException e) { + LOG.error("Could not read the value from the module file: {}", e.getMessage()); + } + return null; + } + + /** + * Gets the current module directory + * + * @return the module directory + */ + public String getModuleDirectory() { + return moduleDirectory; + } + + /** + * Sets the current module directory + * + * @param moduleDirectory The module directory + */ + public void setModuleDirectory(String moduleDirectory) { + this.moduleDirectory = moduleDirectory; + } + + /** + * Gets all activated modules + * + * @return all activated modules + */ + public HashMap<String, ActivatedModule> getActivated_modules() { + return activated_modules; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/SheepstarModule.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/SheepstarModule.java new file mode 100644 index 0000000..5decfca --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/module/SheepstarModule.java @@ -0,0 +1,99 @@ +package xyz.sheepstar.util.module; + +import de.gnmyt.sqltoolkit.storage.SQLTable; +import net.dv8tion.jda.api.JDA; +import org.apache.commons.io.FileUtils; +import xyz.sheepstar.util.Sheepstar; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.mapper.JSONContent; + +import java.io.File; +import java.io.IOException; +import java.net.URL; + +public class SheepstarModule { + + private SheepstarImpl api; + private File dataFolder; + private Module info; + private String moduleJar; + + /** + * Runs when the module is being enabled + */ + public void onEnable() { + } + + /** + * Runs when the module is being disabled + */ + public void onDisable() { + } + + /** + * Gets the JDA + * + * @return the JDA + */ + public JDA getJDA() { + return api.getJDA(); + } + + /** + * Gets the sheepstar instance + * + * @return the sheepstar instance + */ + public Sheepstar getAPI() { + return api; + } + + /** + * Gets the data folder from the module + * + * @return the data folder from the module + */ + public File getDataFolder() { + return dataFolder; + } + + /** + * Gets the module info + * + * @return the module info + */ + public Module getInfo() { + return info; + } + + /** + * Loads a json resource from the data folder + * + * @param fileName the file you want to load + * @return the created json content + */ + public JSONContent loadResource(String fileName) { + return new JSONContent(new File(dataFolder.getPath() + "/" + fileName)); + } + + /** + * Registers database tables + * + * @param tables The tables you want to register + */ + public void registerTable(SQLTable... tables) { + for (SQLTable current : tables) api.getDatabase().getTableFactory().register(current); + } + + /** + * Copies a file from the module resources to the data folder + * + * @param resourceName the file you want to copy + * @param fileName the name of the file you want to copy to + */ + public void copyFromResource(String resourceName, String fileName) throws IOException { + URL input = new URL(String.format("jar:file:%s!/%s", api.getConfig().getModuleDirectory() + "/" + moduleJar, resourceName)); + + FileUtils.copyInputStreamToFile(input.openConnection().getInputStream(), new File(dataFolder.getPath() + "/" + fileName)); + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/DatabaseCheckerThread.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/DatabaseCheckerThread.java new file mode 100644 index 0000000..f4e437f --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/DatabaseCheckerThread.java @@ -0,0 +1,39 @@ +package xyz.sheepstar.util.sql; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import xyz.sheepstar.util.SheepstarImpl; +import xyz.sheepstar.util.action.RepeatedAction; + +public class DatabaseCheckerThread extends RepeatedAction { + + private final static Logger LOG = LoggerFactory.getLogger(DatabaseCheckerThread.class); + + private final SheepstarImpl api; + + /** + * Constructor of the {@link DatabaseCheckerThread} + * + * @param api The {@link SheepstarImpl} instance + */ + public DatabaseCheckerThread(SheepstarImpl api) { + this.api = api; + } + + @Override + public long time() { + return 5; + } + + @Override + public void execute() { + try { + api.getDatabase().getConnection().prepareStatement("SELECT 1").executeQuery(); + } catch (Exception e) { + if (api.getDatabase().getConnection() != null) + api.getDatabase().disconnect(); + LOG.info("Database is not connected, reconnecting..."); + api.getDatabase().connect(); + } + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepDatabase.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepDatabase.java new file mode 100644 index 0000000..459832f --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepDatabase.java @@ -0,0 +1,48 @@ +package xyz.sheepstar.util.sql; + +import de.gnmyt.sqltoolkit.drivers.MySQLConnection; +import xyz.sheepstar.util.SheepstarImpl; + +import java.sql.Connection; + + +public class SheepDatabase extends MySQLConnection { + + private final SheepstarImpl api; + + /** + * The basis constructor of the {@link SheepDatabase} + * + * @param api The current instance of the sheepstar api + * @param hostname The hostname of the database you want to connect + * @param username The username of the database you want to connect + * @param password The password of the database you want to connect + * @param database The database you want to connect + */ + public SheepDatabase(SheepstarImpl api, String hostname, String username, String password, String database) { + super(hostname, username, password, database); + this.api = api; + this.updateSettings() + .useSSL(true) + .autoReconnect(true) + .maxReconnects(3); + } + + /** + * Gets the connection of the database + * + * @return the connection of the database + */ + public Connection getConnection() { + return con; + } + + /** + * Gets the Sheepstar instance + * + * @return the sheepstar instance + */ + public SheepstarImpl getAPI() { + return api; + } +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepManager.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepManager.java new file mode 100644 index 0000000..f06408c --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SheepManager.java @@ -0,0 +1,65 @@ +package xyz.sheepstar.util.sql; + +import com.google.common.base.CaseFormat; +import de.gnmyt.sqltoolkit.storage.SQLTable; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; + +public abstract class SheepManager extends SQLTable { + + protected final SheepstarImpl api = SheepstarCore.getSheepstar(); + + public SheepManager() { + super(SheepstarCore.getSheepstar().getDatabase()); + } + + public SheepManager table(Class<? extends SQLTable> clazz) { + return (SheepManager) api.getDatabase().getTableFactory().getTable(clazz); + } + + public boolean containsRow(String row, Object value) { + return select().where(row, value).getResult().exists(); + } + + protected int getRowCount(String whereColumn, String whereValue) { + return select().where(whereColumn, whereValue).getResult().getRowCount(); + } + + protected int getRowCount() { + return select().getResult().getRowCount(); + } + + protected void updateString(String whereColumn, Object beforeValue, String column, Object newValue) { + update().where(whereColumn, beforeValue).set(column, newValue).execute(); + } + + protected Object get(String whereColumn, Object value, String resultColumn) { + return select().where(whereColumn, value).getResult().getObject(resultColumn); + } + + protected String getString(String whereColumn, Object whereValue, String resultColumn) { + return get(whereColumn, whereValue, resultColumn).toString(); + } + + protected Object getInteger(String whereColumn, Object whereValue, String resultColumn) { + return select().where(whereColumn, whereValue).getResult().getObject(resultColumn); + } + + protected String getUpperString(String whereColumn, Object whereValue, String resultColumn) { + return getString(whereColumn, whereValue, resultColumn).toUpperCase(); + } + + protected String getLowerString(String whereColumn, Object whereValue, String resultColumn) { + return getString(whereColumn, whereValue, resultColumn).toLowerCase(); + } + + protected String getCamelString(String whereColumn, Object whereValue, String resultColumn) { + return CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, getString(whereColumn, whereValue, resultColumn)); + } + + protected void delete(String column, Object value) { + delete().where(column, value).execute(); + } + + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SimpleDeletionProcess.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SimpleDeletionProcess.java new file mode 100644 index 0000000..7b0ca29 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/SimpleDeletionProcess.java @@ -0,0 +1,63 @@ +package xyz.sheepstar.util.sql; + +import net.dv8tion.jda.api.JDA; +import xyz.sheepstar.core.SheepstarCore; +import xyz.sheepstar.util.SheepstarImpl; + +public abstract class SimpleDeletionProcess extends Thread { + + protected SheepstarImpl api = SheepstarCore.getSheepstar(); + protected JDA jda = api.getJDA(); + + /** + * The number of seconds after which the logic should be executed again + * + * @return the amount of time seconds + */ + public int time() { + return 5000; + } + + /** + * The name of the table you want to use + * + * @return the name of the table + */ + public abstract String tableName(); + + /** + * The column of the table you want to get the list from + * + * @return the column of the table + */ + public abstract String tableColumn(); + + /** + * Your deletion logic + * + * @param row The row you should check + * @return <code>true</code> if the row should be deleted, otherwise <code>false</code> + */ + public abstract boolean shouldDelete(String row); + + @Override + public void run() { + runLogic(); + try { + Thread.sleep(time()); + } catch (InterruptedException ignored) { + } + run(); + } + + /** + * Runs the deletion logic + */ + public void runLogic() { + api.getDatabase().selectFrom(tableName()).getResult().getList(tableColumn()).forEach(row -> { + if (shouldDelete(row)) + api.getDatabase().deleteFrom(tableName()).where(tableColumn(), row).execute(); + }); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/StorageMedium.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/StorageMedium.java new file mode 100644 index 0000000..e7796ba --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/sql/StorageMedium.java @@ -0,0 +1,80 @@ +package xyz.sheepstar.util.sql; + +import net.dv8tion.jda.api.entities.Guild; + +import java.util.ArrayList; +import java.util.HashMap; + +public abstract class StorageMedium extends SheepManager { + + public abstract boolean useGuild(); + + @Override + protected void tableFields() { + if (useGuild()) string("guildID", 255, false, ""); + string("keyName", 255, false, ""); + string("value", 2000, false, ""); + } + + public boolean exists(String key) { + return containsRow("keyName", key); + } + + public boolean exists(Guild guild, String key) { + return select().where("guildID", guild.getId()).where("keyName", key).getResult().getRowCount() != 0; + } + + public void insert(String key, String value) { + insert().value("keyName", key).value("value", value).execute(); + } + + public void insert(Guild guild, String key, String value) { + insert().value("guildID", guild.getId()).value("keyName", key).value("value", value) + .execute(); + } + + public void update(String key, String newValue) { + update().where("keyName", key).set("value", newValue).execute(); + } + + public void update(Guild guild, String key, String newValue) { + update().where("guildID", guild.getId()).where("keyName", key).set("value", newValue).execute(); + } + + public void delete(String key) { + delete("keyName", key); + } + + public void delete(Guild guild, String key) { + delete().where("guildID", guild.getId()).where("keyName", key).execute(); + } + + public String get(String key) { + return getString("keyName", key, "value"); + } + + public String get(Guild guild, String key) { + return select().where("guildID", guild.getId()).where("keyName", key).getResult().getString("value"); + } + + public ArrayList<HashMap<String, Object>> getList(String key) { + return select().where("keyName", key).getResult().getList(); + } + + public ArrayList<HashMap<String, Object>> getList(Guild guild, String key) { + return select().where("guildID", guild.getId()).where("keyName", key).getResult().getList(); + } + + public void insertUpdate(String key, String value) { + if (exists(key)) + update(key, value); + else insert(key, value); + } + + public void insertUpdate(Guild guild, String key, String value) { + if (exists(guild, key)) + update(guild, key, value); + else insert(guild, key, value); + } + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidation.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidation.java new file mode 100644 index 0000000..1fc13f3 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidation.java @@ -0,0 +1,13 @@ +package xyz.sheepstar.util.validation.trigger; + +public abstract class TriggerValidation { + + /** + * Validates a value + * + * @param value The value to validate + * @return <code>true</code> if the value is valid, otherwise <code>false</code> + */ + public abstract boolean validate(Object value); + +} diff --git a/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidator.java b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidator.java new file mode 100644 index 0000000..c215f65 --- /dev/null +++ b/SheepstarCoreV1/src/main/java/xyz/sheepstar/util/validation/trigger/TriggerValidator.java @@ -0,0 +1,53 @@ +package xyz.sheepstar.util.validation.trigger; + +import java.util.HashMap; +import java.util.Map; + +public class TriggerValidator { + + private final HashMap<Class<? extends TriggerValidation>, TriggerValidation> triggers = new HashMap<>(); + + /** + * Create a new trigger + * + * @param triggerClass The class of the validation trigger + * @param trigger The validation schema + */ + public void createTrigger(Class<? extends TriggerValidation> triggerClass, TriggerValidation trigger) { + triggers.put(triggerClass, trigger); + } + + /** + * Deletes a trigger + * + * @param triggerClass The class of the validation trigger + */ + public void deleteTrigger(Class<? extends TriggerValidation> triggerClass) { + triggers.remove(triggerClass); + } + + /** + * Checks if the value is triggered + * + * @param triggerClass The class of the validation trigger + * @param triggerValue The value to check + * @return <code>true</code> if the trigger is triggered, otherwise <code>false</code> + */ + public boolean isTriggered(Class<? extends TriggerValidation> triggerClass, Object triggerValue) { + return triggers.get(triggerClass).validate(triggerValue); + } + + /** + * Checks every trigger if the value is triggered + * + * @param triggerValue The value to check + * @return <code>true</code> if the trigger is triggered, otherwise <code>false</code> + */ + public boolean isTriggered(Object triggerValue) { + for (Map.Entry<Class<? extends TriggerValidation>, TriggerValidation> map : triggers.entrySet()) { + if (isTriggered(map.getKey(), triggerValue)) return true; + } + return false; + } + +} diff --git a/SheepstarCoreV1/src/main/resources/log4j.properties b/SheepstarCoreV1/src/main/resources/log4j.properties new file mode 100644 index 0000000..60cd809 --- /dev/null +++ b/SheepstarCoreV1/src/main/resources/log4j.properties @@ -0,0 +1,18 @@ +log4j.rootLogger=INFO, CONSOLE, FILE + +# Write to console +log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender +log4j.appender.CONSOLE.layout=com.jcabi.log.MulticolorLayout +log4j.appender.CONSOLE.layout.ConversionPattern=[%d{HH:mm:ss} %color{%p}]: %m%n +log4j.appender.CONSOLE.Threshold = ERROR, WARN, INFO +log4j.appender.CONSOLE.layout.Levels=INFO:2;32,ERROR:2;31,WARN:2;33 + +# Write to logfile +log4j.appender.FILE=org.apache.log4j.rolling.RollingFileAppender +log4j.appender.FILE.RollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy +log4j.appender.FILE.RollingPolicy.FileNamePattern=logs/%d{yyyy-MM-dd}.log +log4j.appender.FILE.layout=org.apache.log4j.PatternLayout +log4j.appender.FILE.layout.ConversionPattern=[%d{HH:mm:ss} %p] [%c{1}:%L]: %m%n + +# Turn off custom loggers +log4j.logger.club.minnced.discord.webhook.WebhookClient=OFF \ No newline at end of file