-
-
Notifications
You must be signed in to change notification settings - Fork 20
GH-990 Add custom command feature #1064
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
79e0be8
Add custom command feature
vLuckyyy 4928372
Add comment.
vLuckyyy 573a72d
Merge branch 'master' into add-custom-command-feature
vLuckyyy e9b8431
move to okaeri configs.
vLuckyyy 832e2fe
Refactor custom commands to improve maintainability
vLuckyyy c9d7d1c
fix.
vLuckyyy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
36 changes: 36 additions & 0 deletions
36
eternalcore-core/src/main/java/com/eternalcode/core/feature/customcommand/CustomCommand.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package com.eternalcode.core.feature.customcommand; | ||
|
|
||
| import com.eternalcode.multification.notice.Notice; | ||
| import java.io.Serializable; | ||
| import java.util.List; | ||
|
|
||
| public class CustomCommand implements Serializable { | ||
|
|
||
| private String name; | ||
| private List<String> aliases; | ||
| private Notice message; | ||
|
|
||
| public CustomCommand() {} | ||
|
|
||
| public CustomCommand(String name, List<String> aliases, Notice message) { | ||
| this.name = name; | ||
| this.aliases = aliases; | ||
| this.message = message; | ||
| } | ||
vLuckyyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| public static CustomCommand of(String commandName, List<String> aliases, Notice message) { | ||
| return new CustomCommand(commandName, aliases, message); | ||
| } | ||
|
|
||
| public String getName() { | ||
| return name; | ||
| } | ||
|
|
||
| public List<String> getAliases() { | ||
| return aliases; | ||
| } | ||
vLuckyyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| public Notice getMessage() { | ||
| return message; | ||
| } | ||
| } | ||
40 changes: 40 additions & 0 deletions
40
.../src/main/java/com/eternalcode/core/feature/customcommand/CustomCommandBukkitWrapper.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package com.eternalcode.core.feature.customcommand; | ||
|
|
||
| import com.eternalcode.core.notice.NoticeService; | ||
| import com.eternalcode.multification.notice.Notice; | ||
| import dev.rollczi.litecommands.util.StringUtil; | ||
| import java.util.List; | ||
| import org.bukkit.command.Command; | ||
| import org.bukkit.command.CommandSender; | ||
| import org.jetbrains.annotations.NotNull; | ||
|
|
||
| public class CustomCommandBukkitWrapper extends Command { | ||
|
|
||
| private static final String EMPTY_USAGE_MESSAGE = StringUtil.EMPTY; | ||
| private static final String EMPTY_DESCRIPTION_MESSAGE = StringUtil.EMPTY; | ||
|
|
||
| private final NoticeService noticeService; | ||
| private final Notice message; | ||
|
|
||
| protected CustomCommandBukkitWrapper( | ||
| @NotNull String name, | ||
| @NotNull List<String> aliases, | ||
| NoticeService noticeService, | ||
| Notice message | ||
| ) { | ||
| super(name, EMPTY_DESCRIPTION_MESSAGE, EMPTY_USAGE_MESSAGE, aliases); | ||
|
|
||
| this.noticeService = noticeService; | ||
| this.message = message; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean execute(@NotNull CommandSender commandSender, @NotNull String s, @NotNull String[] strings) { | ||
| this.noticeService.create() | ||
| .notice(this.message) | ||
| .sender(commandSender) | ||
| .send(); | ||
|
|
||
| return true; | ||
| } | ||
| } |
133 changes: 133 additions & 0 deletions
133
...re-core/src/main/java/com/eternalcode/core/feature/customcommand/CustomCommandConfig.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| package com.eternalcode.core.feature.customcommand; | ||
|
|
||
| import com.eternalcode.core.configuration.AbstractConfigurationFile; | ||
| import com.eternalcode.core.injector.annotations.component.ConfigurationFile; | ||
| import com.eternalcode.multification.notice.Notice; | ||
| import eu.okaeri.configs.annotation.Comment; | ||
| import eu.okaeri.configs.annotation.Header; | ||
| import java.io.File; | ||
| import java.time.Duration; | ||
| import java.util.List; | ||
| import net.kyori.adventure.bossbar.BossBar.Color; | ||
| import net.kyori.adventure.bossbar.BossBar.Overlay; | ||
|
|
||
| @ConfigurationFile | ||
| @Header({ | ||
| " ", | ||
| "Custom commands configuration", | ||
| "", | ||
| "This file allows you to define your own commands using simple YAML configuration.", | ||
| "Each command entry supports multiple display formats: chat, title, subtitle, action bar, bossbar and sound.", | ||
| "", | ||
| "Example usage:", | ||
| "- Display your Discord link with a title and chat message (/discord)", | ||
| "- Promote your store using a bossbar (/store)", | ||
| "- Show server rules with a subtitle and timed title (/rules)", | ||
| "", | ||
| "You can test and generate these easily using:", | ||
| "https://www.eternalcode.pl/notification-generator" | ||
| }) | ||
| public class CustomCommandConfig extends AbstractConfigurationFile { | ||
vLuckyyy marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @Comment({ | ||
| " ", | ||
| "# Custom commands", | ||
| "#", | ||
| "# Each command defines its name, aliases and message configuration.", | ||
| "#", | ||
| "# WARNING: You must restart the server after editing this file for changes to take effect.", | ||
| }) | ||
| public List<CustomCommand> commands = List.of( | ||
| CustomCommand.of( | ||
| "help", | ||
| List.of("info"), | ||
| Notice.builder() | ||
| .title("<rainbow>Welcome to EternalCore!</rainbow>") | ||
| .subtitle("<gray>Use /help to get started</gray>") | ||
| .times(Duration.ofMillis(500), Duration.ofSeconds(3), Duration.ofMillis(500)) | ||
| .actionBar("<green>Need support? Try /discord</green>") | ||
| .chat( | ||
| " ", | ||
| "<yellow>To add your own commands, edit <aqua>custom-commands.yml</aqua> and restart the server.", | ||
| "<gray>Use our generator to create nice looking messages:</gray>", | ||
| "<aqua>https://www.eternalcode.pl/notification-generator</aqua>" | ||
| ).build() | ||
| ), | ||
| CustomCommand.of( | ||
| "discord", | ||
| List.of("dc"), | ||
| Notice.builder() | ||
| .title("<blue>🎧 Discord</blue>") | ||
| .subtitle("<gray>Join the community!</gray>") | ||
| .times(Duration.ofMillis(300), Duration.ofSeconds(2), Duration.ofMillis(300)) | ||
| .chat( | ||
| " ", | ||
| "<blue>🎧 Join our Discord server:", | ||
| "<aqua>https://discord.gg/yourserver</aqua>", | ||
| " ", | ||
| "<gray>Talk with the team, suggest features, get help.</gray>" | ||
| ).build() | ||
| ), | ||
| CustomCommand.of( | ||
| "store", | ||
| List.of("shop"), | ||
| Notice.builder() | ||
| .bossBar( | ||
| Color.YELLOW, Overlay.NOTCHED_10, Duration.ofSeconds(5), 1.0, | ||
| "<gold>🛒 Visit our store – support the server & get cool perks!") | ||
| .chat( | ||
| " ", | ||
| "<gold>🛒 Visit our server store:", | ||
| "<aqua>https://store.yourserver.com</aqua>", | ||
| " ", | ||
| "<gray>Your support keeps us alive ❤</gray>" | ||
| ).build() | ||
| ), | ||
| CustomCommand.of( | ||
| "vote", | ||
| List.of("votes"), | ||
| Notice.builder() | ||
| .actionBar("<yellow>★ Vote daily and earn rewards!</yellow>") | ||
| .chat( | ||
| " ", | ||
| "<yellow>★ Vote for our server and receive daily rewards!", | ||
| "<aqua>https://yourserver.com/vote</aqua>", | ||
| " ", | ||
| "<gray>Each vote helps us grow!</gray>" | ||
| ).build() | ||
| ), | ||
| CustomCommand.of( | ||
| "rules", | ||
| List.of(), | ||
| Notice.builder() | ||
| .title("<red>📜 Server Rules</red>") | ||
| .subtitle("<gray>Read before playing!</gray>") | ||
| .times(Duration.ofMillis(300), Duration.ofSeconds(3), Duration.ofMillis(300)) | ||
| .actionBar("<red>No cheating, griefing or toxicity – be respectful!</red>") | ||
| .chat( | ||
| " ", | ||
| "<red>📜 Server Rules:", | ||
| "<aqua>https://yourserver.com/rules</aqua>", | ||
| " ", | ||
| "<gray>Breaking rules may result in a ban.</gray>" | ||
| ).build() | ||
| ), | ||
| CustomCommand.of( | ||
| "map", | ||
| List.of("dynmap"), | ||
| Notice.builder() | ||
| .chat( | ||
| " ", | ||
| "<green>🗺 Live Server Map:", | ||
| "<aqua>https://map.yourserver.com</aqua>", | ||
| " ", | ||
| "<gray>See what others are building in real time!</gray>" | ||
| ).build() | ||
| ) | ||
| ); | ||
|
|
||
| @Override | ||
| public File getConfigFile(File dataFolder) { | ||
| return new File(dataFolder, "custom-commands.yml"); | ||
| } | ||
| } | ||
65 changes: 65 additions & 0 deletions
65
...-core/src/main/java/com/eternalcode/core/feature/customcommand/CustomCommandRegistry.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| package com.eternalcode.core.feature.customcommand; | ||
|
|
||
| import com.eternalcode.core.injector.annotations.Inject; | ||
| import com.eternalcode.core.injector.annotations.component.Service; | ||
| import com.eternalcode.core.notice.NoticeService; | ||
| import dev.rollczi.litecommands.util.StringUtil; | ||
| import java.lang.reflect.Field; | ||
| import org.bukkit.Server; | ||
| import org.bukkit.command.CommandMap; | ||
|
|
||
| @Service | ||
| public class CustomCommandRegistry { | ||
|
|
||
| private static final String FALLBACK_PREFIX = "eternalcore"; | ||
|
|
||
| private final CustomCommandConfig customCommandConfig; | ||
| private final NoticeService noticeService; | ||
| private final Server server; | ||
|
|
||
| private CommandMap commandMap; | ||
|
|
||
| @Inject | ||
| public CustomCommandRegistry(CustomCommandConfig customCommandConfig, NoticeService noticeService, Server server) { | ||
| this.customCommandConfig = customCommandConfig; | ||
| this.noticeService = noticeService; | ||
| this.server = server; | ||
|
|
||
| this.registerCustomCommands(); | ||
| } | ||
|
|
||
| public void registerCustomCommands() { | ||
| for (CustomCommand customCommand : this.customCommandConfig.commands) { | ||
| this.registerCustomCommand(customCommand); | ||
| } | ||
| } | ||
|
|
||
| private void registerCustomCommand(CustomCommand customCommand) { | ||
| CustomCommandBukkitWrapper customCommandBukkitWrapper = new CustomCommandBukkitWrapper( | ||
| customCommand.getName(), | ||
| customCommand.getAliases(), | ||
| this.noticeService, | ||
| customCommand.getMessage() | ||
| ); | ||
|
|
||
| this.commandMap().register(FALLBACK_PREFIX, customCommandBukkitWrapper); | ||
| } | ||
|
|
||
| CommandMap commandMap() { | ||
| if (this.commandMap == null) { | ||
| try { | ||
| Field commandMapField = this.server.getClass().getDeclaredField("commandMap"); | ||
| commandMapField.setAccessible(true); | ||
|
|
||
| this.commandMap = (CommandMap) commandMapField.get(this.server); | ||
| } | ||
| catch (NoSuchFieldException | IllegalAccessException exception) { | ||
| throw new RuntimeException( | ||
| "Failed to get CommandMap from the server, this might be due to a server version incompatibility.", | ||
| exception); | ||
| } | ||
| } | ||
|
|
||
| return this.commandMap; | ||
| } | ||
| } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.