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