Finished Kotlin conversion, Command2MC stuff remains

This commit is contained in:
Norbi Peti 2023-04-17 21:04:00 +02:00
parent 1d88d3e859
commit 30a2fe0b68
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
23 changed files with 564 additions and 643 deletions

View file

@ -1 +0,0 @@
lombok.var.flagUsage = ALLOW

View file

@ -14,7 +14,7 @@ import java.util.Optional;
@CommandClass @CommandClass
public class ChromaCommand extends ICommand2MC { public class ChromaCommand extends ICommand2MC {
public ChromaCommand() { public ChromaCommand() {
getManager().addParamConverter(ButtonPlugin.class, name -> manager.addParamConverter(ButtonPlugin.class, name ->
(ButtonPlugin) Optional.ofNullable(Bukkit.getPluginManager().getPlugin(name)) (ButtonPlugin) Optional.ofNullable(Bukkit.getPluginManager().getPlugin(name))
.filter(plugin -> plugin instanceof ButtonPlugin).orElse(null), .filter(plugin -> plugin instanceof ButtonPlugin).orElse(null),
"No Chroma plugin found by that name.", () -> Arrays.stream(Bukkit.getPluginManager().getPlugins()) "No Chroma plugin found by that name.", () -> Arrays.stream(Bukkit.getPluginManager().getPlugins())

View file

@ -1,102 +1,98 @@
package buttondevteam.core; package buttondevteam.core
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI
import buttondevteam.lib.architecture.ButtonPlugin; import buttondevteam.lib.architecture.ButtonPlugin
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.Component
import buttondevteam.lib.chat.Command2; import buttondevteam.lib.architecture.Component.Companion.components
import buttondevteam.lib.chat.Command2.Subcommand; import buttondevteam.lib.architecture.Component.Companion.setComponentEnabled
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.Command2.OptionalArg
import buttondevteam.lib.chat.CustomTabCompleteMethod; import buttondevteam.lib.chat.Command2.Subcommand
import buttondevteam.lib.chat.ICommand2MC; import buttondevteam.lib.chat.CommandClass
import lombok.val; import buttondevteam.lib.chat.CustomTabCompleteMethod
import org.bukkit.Bukkit; import buttondevteam.lib.chat.ICommand2MC
import org.bukkit.command.CommandSender; import org.bukkit.Bukkit
import org.bukkit.plugin.Plugin; import org.bukkit.command.CommandSender
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.Plugin
import org.bukkit.plugin.java.JavaPlugin
import java.util.*
import java.util.stream.Stream
import java.util.Arrays; @CommandClass(modOnly = true, helpText = ["Component command", "Can be used to enable/disable/list components"])
import java.util.Optional; class ComponentCommand : ICommand2MC() {
import java.util.stream.Stream; init {
manager.addParamConverter(
Plugin::class.java, { arg -> Bukkit.getPluginManager().getPlugin(arg) },
"Plugin not found!"
) { Bukkit.getPluginManager().plugins.map { obj -> obj.name } }
}
@CommandClass(modOnly = true, helpText = { @Subcommand(helpText = ["Enable component", "Temporarily or permanently enables a component."])
"Component command", fun enable(sender: CommandSender, plugin: Plugin, component: String, @OptionalArg permanent: Boolean): Boolean {
"Can be used to enable/disable/list components" if (plugin is ButtonPlugin) {
}) if (!plugin.justReload()) {
public class ComponentCommand extends ICommand2MC { sender.sendMessage("§cCouldn't reload config, check console.")
public ComponentCommand() { return true
getManager().addParamConverter(Plugin.class, arg -> Bukkit.getPluginManager().getPlugin(arg), "Plugin not found!", }
() -> Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName)::iterator); } else plugin.reloadConfig() //Reload config so the new config values are read - All changes are saved to disk on disable
} return enable_disable(sender, plugin, component, true, permanent)
}
@Subcommand(helpText = { @Subcommand(helpText = ["Disable component", "Temporarily or permanently disables a component."])
"Enable component", fun disable(sender: CommandSender, plugin: Plugin, component: String, @OptionalArg permanent: Boolean): Boolean {
"Temporarily or permanently enables a component." return enable_disable(sender, plugin, component, false, permanent)
}) }
public boolean enable(CommandSender sender, Plugin plugin, String component, @Command2.OptionalArg boolean permanent) {
if (plugin instanceof ButtonPlugin) {
if (!((ButtonPlugin) plugin).justReload()) {
sender.sendMessage("§cCouldn't reload config, check console.");
return true;
}
} else
plugin.reloadConfig(); //Reload config so the new config values are read - All changes are saved to disk on disable
return enable_disable(sender, plugin, component, true, permanent);
}
@Subcommand(helpText = { @Subcommand(helpText = ["List components", "Lists all of the registered Chroma components"])
"Disable component", fun list(sender: CommandSender, @OptionalArg plugin: String?): Boolean {
"Temporarily or permanently disables a component." sender.sendMessage("§6List of components:")
}) //If plugin is null, don't check for it
public boolean disable(CommandSender sender, Plugin plugin, String component, @Command2.OptionalArg boolean permanent) { components.values.stream().filter { c -> plugin == null || c.plugin.name.equals(plugin, ignoreCase = true) }
return enable_disable(sender, plugin, component, false, permanent); .map { c -> "${c.plugin.name} - ${c.javaClass.simpleName} - ${if (c.isEnabled) "en" else "dis"}abled" }
} .forEach { message -> sender.sendMessage(message) }
return true
}
@Subcommand(helpText = { @CustomTabCompleteMethod(param = "component", subcommand = ["enable", "disable"])
"List components", fun componentTabcomplete(plugin: Plugin): Iterable<String> {
"Lists all of the registered Chroma components" return Iterable { getPluginComponents(plugin).map { c -> c.javaClass.simpleName }.iterator() }
}) }
public boolean list(CommandSender sender, @Command2.OptionalArg String plugin) {
sender.sendMessage("§6List of components:");
Component.getComponents().values().stream().filter(c -> plugin == null || c.getPlugin().getName().equalsIgnoreCase(plugin)) //If plugin is null, don't check
.map(c -> c.getPlugin().getName() + " - " + c.getClass().getSimpleName() + " - " + (c.isEnabled() ? "en" : "dis") + "abled").forEach(sender::sendMessage);
return true;
}
@CustomTabCompleteMethod(param = "component", subcommand = {"enable", "disable"}) @CustomTabCompleteMethod(param = "plugin", subcommand = ["list", "enable", "disable"], ignoreTypeCompletion = true)
public Iterable<String> componentTabcomplete(Plugin plugin) { fun pluginTabcomplete(): Iterable<String> {
return getPluginComponents(plugin).map(c -> c.getClass().getSimpleName())::iterator; return Iterable { components.values.stream().map { it.plugin }.distinct().map { it.name }.iterator() }
} }
@CustomTabCompleteMethod(param = "plugin", subcommand = {"list", "enable", "disable"}, ignoreTypeCompletion = true) private fun enable_disable(
public Iterable<String> pluginTabcomplete() { sender: CommandSender,
return Component.getComponents().values().stream().map(Component::getPlugin) plugin: Plugin,
.distinct().map(Plugin::getName)::iterator; component: String,
} enable: Boolean,
permanent: Boolean
): Boolean {
try {
val oc = getComponentOrError(plugin, component, sender)
if (!oc.isPresent) return true
setComponentEnabled(oc.get(), enable)
if (permanent) oc.get().shouldBeEnabled.set(enable)
sender.sendMessage("${oc.get().javaClass.simpleName} ${if (enable) "en" else "dis"}abled ${if (permanent) "permanently" else "temporarily"}.")
} catch (e: Exception) {
TBMCCoreAPI.SendException(
"Couldn't " + (if (enable) "en" else "dis") + "able component " + component + "!",
e,
plugin as JavaPlugin
)
}
return true
}
private boolean enable_disable(CommandSender sender, Plugin plugin, String component, boolean enable, boolean permanent) { private fun getPluginComponents(plugin: Plugin): Stream<Component<out JavaPlugin>> {
try { return components.values.stream().filter { c -> plugin.name == c.plugin.name }
val oc = getComponentOrError(plugin, component, sender); }
if (!oc.isPresent())
return true;
Component.setComponentEnabled(oc.get(), enable);
if (permanent)
oc.get().shouldBeEnabled.set(enable);
sender.sendMessage(oc.get().getClass().getSimpleName() + " " + (enable ? "en" : "dis") + "abled " + (permanent ? "permanently" : "temporarily") + ".");
} catch (Exception e) {
TBMCCoreAPI.SendException("Couldn't " + (enable ? "en" : "dis") + "able component " + component + "!", e, (JavaPlugin) plugin);
}
return true;
}
private Stream<Component<? extends JavaPlugin>> getPluginComponents(Plugin plugin) { private fun getComponentOrError(plugin: Plugin, arg: String, sender: CommandSender): Optional<Component<*>> {
return Component.getComponents().values().stream() // TODO: Extend param converter to support accessing previous params
.filter(c -> plugin.getName().equals(c.getPlugin().getName())); val oc = getPluginComponents(plugin).filter { it.javaClass.simpleName.equals(arg, ignoreCase = true) }.findAny()
} if (!oc.isPresent) sender.sendMessage("§cComponent not found!")
return oc
private Optional<Component<?>> getComponentOrError(Plugin plugin, String arg, CommandSender sender) { }
val oc = getPluginComponents(plugin).filter(c -> c.getClass().getSimpleName().equalsIgnoreCase(arg)).findAny();
if (!oc.isPresent())
sender.sendMessage("§cComponent not found!"); //^ Much simpler to solve in the new command system
return oc;
}
} }

View file

@ -91,13 +91,13 @@ class MainPlugin : ButtonPlugin() {
) )
} }
TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase::class.java) { TBMCPlayer() } TBMCCoreAPI.RegisterUserClass(TBMCPlayerBase::class.java) { TBMCPlayer() }
TBMCChatAPI.RegisterChatChannel(Channel("§fg§f", Color.White, "g", null) TBMCChatAPI.registerChatChannel(Channel("§fg§f", Color.White, "g", null)
.also { Channel.globalChat = it }) //The /ooc ID has moved to the config .also { Channel.globalChat = it }) //The /ooc ID has moved to the config
TBMCChatAPI.RegisterChatChannel(Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null)) TBMCChatAPI.registerChatChannel(Channel("§cADMIN§f", Color.Red, "a", Channel.inGroupFilter(null))
.also { Channel.adminChat = it }) .also { Channel.adminChat = it })
TBMCChatAPI.RegisterChatChannel(Channel("§9MOD§f", Color.Blue, "mod", Channel.inGroupFilter("mod")) TBMCChatAPI.registerChatChannel(Channel("§9MOD§f", Color.Blue, "mod", Channel.inGroupFilter("mod"))
.also { Channel.modChat = it }) .also { Channel.modChat = it })
TBMCChatAPI.RegisterChatChannel( TBMCChatAPI.registerChatChannel(
Channel( Channel(
"§6DEV§f", "§6DEV§f",
Color.Gold, Color.Gold,
@ -105,12 +105,12 @@ class MainPlugin : ButtonPlugin() {
Channel.inGroupFilter("developer") Channel.inGroupFilter("developer")
) )
) // TODO: Make groups configurable ) // TODO: Make groups configurable
TBMCChatAPI.RegisterChatChannel(ChatRoom("§cRED§f", Color.DarkRed, "red")) TBMCChatAPI.registerChatChannel(ChatRoom("§cRED§f", Color.DarkRed, "red"))
TBMCChatAPI.RegisterChatChannel(ChatRoom("§6ORANGE§f", Color.Gold, "orange")) TBMCChatAPI.registerChatChannel(ChatRoom("§6ORANGE§f", Color.Gold, "orange"))
TBMCChatAPI.RegisterChatChannel(ChatRoom("§eYELLOW§f", Color.Yellow, "yellow")) TBMCChatAPI.registerChatChannel(ChatRoom("§eYELLOW§f", Color.Yellow, "yellow"))
TBMCChatAPI.RegisterChatChannel(ChatRoom("§aGREEN§f", Color.Green, "green")) TBMCChatAPI.registerChatChannel(ChatRoom("§aGREEN§f", Color.Green, "green"))
TBMCChatAPI.RegisterChatChannel(ChatRoom("§bBLUE§f", Color.Blue, "blue")) TBMCChatAPI.registerChatChannel(ChatRoom("§bBLUE§f", Color.Blue, "blue"))
TBMCChatAPI.RegisterChatChannel(ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple")) TBMCChatAPI.registerChatChannel(ChatRoom("§5PURPLE§f", Color.DarkPurple, "purple"))
val playerSupplier = Supplier { Bukkit.getOnlinePlayers().map { obj -> obj.name }.asIterable() } val playerSupplier = Supplier { Bukkit.getOnlinePlayers().map { obj -> obj.name }.asIterable() }
command2MC.addParamConverter( command2MC.addParamConverter(
OfflinePlayer::class.java, OfflinePlayer::class.java,

View file

@ -88,7 +88,7 @@ class PlayerListener(val plugin: MainPlugin) : Listener {
fun onPlayerChat(event: AsyncPlayerChatEvent) { fun onPlayerChat(event: AsyncPlayerChatEvent) {
if (event.isCancelled) return //The chat plugin should cancel it after this handler if (event.isCancelled) return //The chat plugin should cancel it after this handler
val cp = TBMCPlayerBase.getPlayer(event.player.uniqueId, TBMCPlayer::class.java) val cp = TBMCPlayerBase.getPlayer(event.player.uniqueId, TBMCPlayer::class.java)
TBMCChatAPI.SendChatMessage(ChatMessage.builder(event.player, cp, event.message).build()) TBMCChatAPI.sendChatMessage(ChatMessage.builder(event.player, cp, event.message).build())
//Not cancelling the original event here, it's cancelled in the chat plugin //Not cancelling the original event here, it's cancelled in the chat plugin
//This way other plugins can deal with the MC formatting if the chat plugin isn't present, but other platforms still get the message //This way other plugins can deal with the MC formatting if the chat plugin isn't present, but other platforms still get the message
} }

View file

@ -45,6 +45,6 @@ public class TestPrepare {
} }
})); }));
Component.registerComponent(Mockito.mock(JavaPlugin.class), new ChannelComponent()); Component.registerComponent(Mockito.mock(JavaPlugin.class), new ChannelComponent());
TBMCChatAPI.RegisterChatChannel(Channel.globalChat = new Channel("§fg§f", Color.White, "g", null)); TBMCChatAPI.registerChatChannel(Channel.globalChat = new Channel("§fg§f", Color.White, "g", null));
} }
} }

View file

@ -31,13 +31,10 @@ class ChannelComponent : Component<JavaPlugin>() {
@CommandClass @CommandClass
private class ChannelCommand(private val channel: Channel) : ICommand2MC() { private class ChannelCommand(private val channel: Channel) : ICommand2MC() {
override fun getCommandPath(): String { override val commandPath: String
return channel.identifier get() = channel.identifier
} override val commandPaths: Array<String>
get() = channel.extraIdentifiers.get().toTypedArray()
override fun getCommandPaths(): Array<String> {
return channel.extraIdentifiers.get().toTypedArray()
}
@Subcommand @Subcommand
fun def(senderMC: Command2MCSender, @OptionalArg @TextArg message: String?) { fun def(senderMC: Command2MCSender, @OptionalArg @TextArg message: String?) {
@ -55,7 +52,7 @@ class ChannelComponent : Component<JavaPlugin>() {
if (channel is ChatRoom) channel.joinRoom(sender) if (channel is ChatRoom) channel.joinRoom(sender)
} }
sender.sendMessage("§6You are now talking in: §b" + user.channel.get().displayName.get()) sender.sendMessage("§6You are now talking in: §b" + user.channel.get().displayName.get())
} else TBMCChatAPI.SendChatMessage( } else TBMCChatAPI.sendChatMessage(
ChatMessage.builder(sender, user, message).fromCommand(true) ChatMessage.builder(sender, user, message).fromCommand(true)
.permCheck(senderMC.permCheck).build(), channel .permCheck(senderMC.permCheck).build(), channel
) )

View file

@ -1,44 +1,48 @@
package buttondevteam.core.component.restart; package buttondevteam.core.component.restart
import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.Channel
import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.Command2.*
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.CommandClass
import buttondevteam.lib.chat.ICommand2MC; import buttondevteam.lib.chat.ICommand2MC
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI.SendSystemMessage
import lombok.Getter; import org.bukkit.Bukkit
import lombok.RequiredArgsConstructor; import org.bukkit.ChatColor
import org.bukkit.Bukkit; import org.bukkit.command.CommandSender
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
@CommandClass(path = "primerestart", modOnly = true, helpText = { @CommandClass(
"§6---- Prime restart ----", // path = "primerestart", modOnly = true, helpText = ["§6---- Prime restart ----", //
"Restarts the server as soon as nobody is online.", // "Restarts the server as soon as nobody is online.", //
"To be loud, type something after, like /primerestart lol (it doesn't matter what you write)", // "To be loud, type something after, like /primerestart lol (it doesn't matter what you write)", //
"To be silent, don't type anything" // "To be silent, don't type anything" //
}) ]
@RequiredArgsConstructor )
public class PrimeRestartCommand extends ICommand2MC { class PrimeRestartCommand : ICommand2MC() {
private final RestartComponent component; @Subcommand
fun def(sender: CommandSender, @TextArg @OptionalArg somethingrandom: String?) {
val isLoud = somethingrandom != null
val component = component as RestartComponent
component.isLoud = isLoud
if (Bukkit.getOnlinePlayers().isNotEmpty()) {
sender.sendMessage("§bPlayers online, restart delayed.")
if (isLoud) SendSystemMessage(
Channel.globalChat,
Channel.RecipientTestResult.ALL,
"${ChatColor.DARK_RED}The server will restart as soon as nobody is online.",
component.restartBroadcast
)
component.isPlsrestart = true
} else {
sender.sendMessage("§bNobody is online. Restarting now.")
if (isLoud) SendSystemMessage(
Channel.globalChat,
Channel.RecipientTestResult.ALL,
"${ChatColor.RED}Nobody is online. Restarting server.",
component.restartBroadcast
)
Bukkit.spigot().restart()
}
}
@Command2.Subcommand companion object {
public void def(CommandSender sender, @Command2.TextArg @Command2.OptionalArg String somethingrandom) { }
loud = somethingrandom != null;
if (Bukkit.getOnlinePlayers().size() > 0) {
sender.sendMessage("§bPlayers online, restart delayed.");
if (loud)
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, ChatColor.DARK_RED + "The server will restart as soon as nobody is online.", component.getRestartBroadcast());
plsrestart = true;
} else {
sender.sendMessage("§bNobody is online. Restarting now.");
if (loud)
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, "§cNobody is online. Restarting server.", component.getRestartBroadcast());
Bukkit.spigot().restart();
}
}
@Getter
private static boolean plsrestart = false;
@Getter
private static boolean loud = false;
} }

View file

@ -9,7 +9,6 @@ import buttondevteam.lib.architecture.Component
import buttondevteam.lib.architecture.ComponentMetadata import buttondevteam.lib.architecture.ComponentMetadata
import buttondevteam.lib.chat.IFakePlayer import buttondevteam.lib.chat.IFakePlayer
import buttondevteam.lib.chat.TBMCChatAPI import buttondevteam.lib.chat.TBMCChatAPI
import lombok.Getter
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.ChatColor import org.bukkit.ChatColor
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
@ -26,9 +25,9 @@ import java.time.ZonedDateTime
@ComponentMetadata(enabledByDefault = false) @ComponentMetadata(enabledByDefault = false)
class RestartComponent : Component<MainPlugin>(), Listener { class RestartComponent : Component<MainPlugin>(), Listener {
public override fun enable() { public override fun enable() {
val scheduledRestartCommand = ScheduledRestartCommand(this) val scheduledRestartCommand = ScheduledRestartCommand()
registerCommand(scheduledRestartCommand) registerCommand(scheduledRestartCommand)
registerCommand(PrimeRestartCommand(this)) registerCommand(PrimeRestartCommand())
registerListener(this) registerListener(this)
restartBroadcast = add("restartCountdown") restartBroadcast = add("restartCountdown")
val restartAt = restartAt.get() val restartAt = restartAt.get()
@ -52,8 +51,10 @@ class RestartComponent : Component<MainPlugin>(), Listener {
private val restartAt = config.getData("restartAt", 12) private val restartAt = config.getData("restartAt", 12)
private var lasttime: Long = 0 private var lasttime: Long = 0
@Getter var isPlsrestart = false
private var restartBroadcast: BroadcastTarget? = null var isLoud = false
lateinit var restartBroadcast: BroadcastTarget
private fun syncStart(hour: Int): Int { private fun syncStart(hour: Int): Int {
val now = ZonedDateTime.now(ZoneId.ofOffset("", ZoneOffset.UTC)) val now = ZonedDateTime.now(ZoneId.ofOffset("", ZoneOffset.UTC))
val secs = now.hour * 3600 + now.minute * 60 + now.second val secs = now.hour * 3600 + now.minute * 60 + now.second
@ -69,12 +70,12 @@ class RestartComponent : Component<MainPlugin>(), Listener {
@EventHandler @EventHandler
fun onPlayerLeave(event: PlayerQuitEvent) { fun onPlayerLeave(event: PlayerQuitEvent) {
if (PrimeRestartCommand.isPlsrestart() if (isPlsrestart
&& !event.quitMessage.equals("Server closed", ignoreCase = true) && !event.quitMessage.equals("Server closed", ignoreCase = true)
&& !event.quitMessage.equals("Server is restarting", ignoreCase = true) && !event.quitMessage.equals("Server is restarting", ignoreCase = true)
) { ) {
if (Bukkit.getOnlinePlayers().size <= 1) { if (Bukkit.getOnlinePlayers().size <= 1) {
if (PrimeRestartCommand.isLoud()) TBMCChatAPI.SendSystemMessage( if (isLoud) TBMCChatAPI.SendSystemMessage(
Channel.globalChat, Channel.globalChat,
Channel.RecipientTestResult.ALL, Channel.RecipientTestResult.ALL,
"§cNobody is online anymore. Restarting.", "§cNobody is online anymore. Restarting.",
@ -83,7 +84,7 @@ class RestartComponent : Component<MainPlugin>(), Listener {
Bukkit.spigot().restart() Bukkit.spigot().restart()
} else if (event.player !is IFakePlayer && System.nanoTime() - 10 * 60 * 1000000000L - lasttime > 0) { //10 minutes passed since last reminder } else if (event.player !is IFakePlayer && System.nanoTime() - 10 * 60 * 1000000000L - lasttime > 0) { //10 minutes passed since last reminder
lasttime = System.nanoTime() lasttime = System.nanoTime()
if (PrimeRestartCommand.isLoud()) TBMCChatAPI.SendSystemMessage( if (isLoud) TBMCChatAPI.SendSystemMessage(
Channel.globalChat, Channel.globalChat,
Channel.RecipientTestResult.ALL, Channel.RecipientTestResult.ALL,
ChatColor.DARK_RED.toString() + "The server will restart as soon as nobody is online.", ChatColor.DARK_RED.toString() + "The server will restart as soon as nobody is online.",

View file

@ -1,68 +1,75 @@
package buttondevteam.core.component.restart; package buttondevteam.core.component.restart
import buttondevteam.core.MainPlugin; import buttondevteam.core.MainPlugin
import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.Channel
import buttondevteam.lib.ScheduledServerRestartEvent; import buttondevteam.lib.ScheduledServerRestartEvent
import buttondevteam.lib.chat.Command2; import buttondevteam.lib.chat.Command2.OptionalArg
import buttondevteam.lib.chat.CommandClass; import buttondevteam.lib.chat.Command2.Subcommand
import buttondevteam.lib.chat.ICommand2MC; import buttondevteam.lib.chat.CommandClass
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.ICommand2MC
import lombok.Getter; import buttondevteam.lib.chat.TBMCChatAPI.SendSystemMessage
import lombok.RequiredArgsConstructor; import org.bukkit.Bukkit
import lombok.Setter; import org.bukkit.boss.BarColor
import org.bukkit.Bukkit; import org.bukkit.boss.BarFlag
import org.bukkit.boss.BarColor; import org.bukkit.boss.BarStyle
import org.bukkit.boss.BarFlag; import org.bukkit.boss.BossBar
import org.bukkit.boss.BarStyle; import org.bukkit.command.CommandSender
import org.bukkit.boss.BossBar; import org.bukkit.scheduler.BukkitTask
import org.bukkit.command.CommandSender; import java.util.function.Consumer
import org.bukkit.scheduler.BukkitTask; import kotlin.properties.Delegates
import javax.annotation.Nonnull; @CommandClass(
modOnly = true, path = "schrestart", helpText = ["Scheduled restart", //
"This command restarts the server 1 minute after it's executed, warning players every 10 seconds.", //
"You can optionally set the amount of seconds to wait before the restart." //
]
)
class ScheduledRestartCommand : ICommand2MC() {
private var restartCounter = 0
private lateinit var restartTask: BukkitTask
@CommandClass(modOnly = true, path = "schrestart", helpText = { @Volatile
"Scheduled restart", // private lateinit var restartBar: BossBar
"This command restarts the server 1 minute after it's executed, warning players every 10 seconds.", //
"You can optionally set the amount of seconds to wait before the restart." //
})
@RequiredArgsConstructor
public class ScheduledRestartCommand extends ICommand2MC {
@Getter
@Setter
private int restartCounter;
private BukkitTask restarttask;
private volatile BossBar restartbar;
@Getter
@Nonnull
private final RestartComponent component;
@Command2.Subcommand private var restartInitialTicks by Delegates.notNull<Int>()
public boolean def(CommandSender sender, @Command2.OptionalArg int seconds) {
if (seconds == 0) seconds = 60; @Subcommand
if (seconds < 10) { fun def(sender: CommandSender, @OptionalArg seconds: Int): Boolean {
sender.sendMessage("§cError: Seconds must be at least 10."); return restart(sender, if (seconds == 0) 60 else seconds)
return false; }
}
final int restarttime = restartCounter = seconds * 20; private fun restart(sender: CommandSender, seconds: Int): Boolean {
restartbar = Bukkit.createBossBar("Server restart in " + seconds + "s", BarColor.RED, BarStyle.SOLID, if (seconds < 10) {
BarFlag.DARKEN_SKY); sender.sendMessage("§cError: Seconds must be at least 10.")
restartbar.setProgress(1); return false
Bukkit.getOnlinePlayers().forEach(p -> restartbar.addPlayer(p)); }
sender.sendMessage("Scheduled restart in " + seconds); restartCounter = seconds * 20
ScheduledServerRestartEvent e = new ScheduledServerRestartEvent(restarttime, this); restartInitialTicks = restartCounter
Bukkit.getPluginManager().callEvent(e); restartBar =
restarttask = Bukkit.getScheduler().runTaskTimer(MainPlugin.instance, () -> { Bukkit.createBossBar("Server restart in " + seconds + "s", BarColor.RED, BarStyle.SOLID, BarFlag.DARKEN_SKY)
if (restartCounter < 0) { restartBar.progress = 1.0
restarttask.cancel(); Bukkit.getOnlinePlayers().forEach { p -> restartBar.addPlayer(p) }
restartbar.getPlayers().forEach(p -> restartbar.removePlayer(p)); sender.sendMessage("Scheduled restart in $seconds")
Bukkit.spigot().restart(); val e = ScheduledServerRestartEvent(restartInitialTicks, this)
} Bukkit.getPluginManager().callEvent(e)
if (restartCounter % 200 == 0 && Bukkit.getOnlinePlayers().size() > 0) restartTask = Bukkit.getScheduler().runTaskTimer(MainPlugin.instance, ::updateRestartTimer, 1, 1)
TBMCChatAPI.SendSystemMessage(Channel.globalChat, Channel.RecipientTestResult.ALL, "§c-- The server is restarting in " + restartCounter / 20 + " seconds!", component.getRestartBroadcast()); return true
restartbar.setProgress(restartCounter / (double) restarttime); }
restartbar.setTitle(String.format("Server restart in %.2f", restartCounter / 20f));
restartCounter--; private fun updateRestartTimer() {
}, 1, 1); if (restartCounter < 0) {
return true; restartTask.cancel()
} restartBar.players.forEach(Consumer { p -> restartBar.removePlayer(p) })
Bukkit.spigot().restart()
}
if (restartCounter % 200 == 0 && Bukkit.getOnlinePlayers().isNotEmpty()) SendSystemMessage(
Channel.globalChat,
Channel.RecipientTestResult.ALL,
"§c-- The server is restarting in " + restartCounter / 20 + " seconds!",
(component as RestartComponent).restartBroadcast
)
restartBar.progress = restartCounter / restartInitialTicks.toDouble()
restartBar.setTitle(String.format("Server restart in %.2f", restartCounter / 20f))
restartCounter--
}
} }

View file

@ -1,25 +1,15 @@
package buttondevteam.lib; package buttondevteam.lib
import buttondevteam.core.component.restart.ScheduledRestartCommand; import buttondevteam.core.component.restart.ScheduledRestartCommand
import lombok.Getter; import org.bukkit.event.Event
import lombok.RequiredArgsConstructor; import org.bukkit.event.HandlerList
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
@Getter class ScheduledServerRestartEvent(val restartTicks: Int, val command: ScheduledRestartCommand) : Event() {
@RequiredArgsConstructor override fun getHandlers(): HandlerList {
public class ScheduledServerRestartEvent extends Event { return handlerList
private static final HandlerList handlers = new HandlerList(); }
private final int restartTicks; companion object {
private final ScheduledRestartCommand command; val handlerList = HandlerList()
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
} }

View file

@ -1,73 +1,55 @@
package buttondevteam.lib; package buttondevteam.lib
import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.Channel
import buttondevteam.lib.chat.ChatMessage; import buttondevteam.core.component.channel.Channel.RecipientTestResult
import lombok.Getter; import buttondevteam.lib.chat.ChatMessage
import lombok.experimental.Delegate; import buttondevteam.lib.player.ChromaGamerBase
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList
import javax.annotation.Nullable;
/** /**
* Make sure to only send the message to users where {@link #shouldSendTo(CommandSender)} returns true. * Make sure to only send the message to users where [.shouldSendTo] returns true.
* *
* @author NorbiPeti * @author NorbiPeti
*
*/ */
@Getter class TBMCChatEvent(
public class TBMCChatEvent extends TBMCChatEventBase { channel: Channel,
public TBMCChatEvent(Channel channel, ChatMessage cm, Channel.RecipientTestResult rtr) { private val cm: ChatMessage,
super(channel, cm.message, rtr.score, rtr.groupID); rtr: RecipientTestResult
this.cm = cm; ) : TBMCChatEventBase(channel, cm.message, rtr.score, rtr.groupID!!) {
}
private static final HandlerList handlers = new HandlerList(); private val isIgnoreSenderPermissions: Boolean get() = cm.permCheck !== cm.sender
@Delegate //<-- Backwards compatibility
private ChatMessage cm;
private boolean isIgnoreSenderPermissions() {
return cm.getPermCheck() != cm.sender;
}
/** /**
* This will allow the sender of the message if {@link #isIgnoreSenderPermissions()} is true. * This will allow the sender of the message if [.isIgnoreSenderPermissions] is true.
*/ */
@Override override fun shouldSendTo(sender: CommandSender): Boolean {
public boolean shouldSendTo(CommandSender sender) { return if (isIgnoreSenderPermissions && sender == cm.sender) true else super.shouldSendTo(sender) //Allow sending the message no matter what
if (isIgnoreSenderPermissions() && sender.equals(this.cm.sender))
return true; //Allow sending the message no matter what
return super.shouldSendTo(sender);
} }
/** /**
* This will allow the sender of the message if {@link #isIgnoreSenderPermissions()} is true. * This will allow the sender of the message if [.isIgnoreSenderPermissions] is true.
*/ */
@Override override fun getMCScore(sender: CommandSender): Int {
public int getMCScore(CommandSender sender) { return if (isIgnoreSenderPermissions && sender == cm.sender) score else super.getMCScore(sender) //Send in the correct group no matter what
if (isIgnoreSenderPermissions() && sender.equals(this.cm.sender))
return getScore(); //Send in the correct group no matter what
return super.getMCScore(sender);
} }
/** /**
* This will allow the sender of the message if {@link #isIgnoreSenderPermissions()} is true. * This will allow the sender of the message if [.isIgnoreSenderPermissions] is true.
*/ */
@Nullable override fun getGroupID(sender: CommandSender): String? {
@Override return if (isIgnoreSenderPermissions && sender == cm.sender) groupID else super.getGroupID(sender) //Send in the correct group no matter what
public String getGroupID(CommandSender sender) {
if (isIgnoreSenderPermissions() && sender.equals(this.cm.sender))
return getGroupID(); //Send in the correct group no matter what
return super.getGroupID(sender);
} }
@Override override fun getHandlers(): HandlerList {
public HandlerList getHandlers() { return handlerList
return handlers; }
}
public static HandlerList getHandlerList() { val sender: CommandSender get() = cm.sender
return handlers; val user: ChromaGamerBase get() = cm.user
} val origin: String get() = cm.origin
companion object {
val handlerList = HandlerList()
}
} }

View file

@ -1,59 +1,47 @@
package buttondevteam.lib; package buttondevteam.lib
import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.Channel
import lombok.Getter; import org.bukkit.command.CommandSender
import lombok.NonNull; import org.bukkit.event.Cancellable
import lombok.Setter; import org.bukkit.event.Event
import org.bukkit.command.CommandSender;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import javax.annotation.Nullable; abstract class TBMCChatEventBase(
val channel: Channel,
@Getter open val message: String,
public abstract class TBMCChatEventBase extends Event implements Cancellable {
private final Channel channel;
private @NonNull String message;
private @Setter boolean cancelled;
/** /**
* The sender's score. * The sender's score.
*/ */
private final int score; val score: Int,
/** /**
* The sender's group ID. * The sender's group ID.
*/ */
private final String groupID; val groupID: String,
) : Event(true), Cancellable {
var isCancelled: Boolean = false
@java.beans.ConstructorProperties({"channel", "message", "score", "groupID"}) /**
public TBMCChatEventBase(Channel channel, String message, int score, String groupID) { * Note: Errors are sent to the sender automatically
super(true); */
this.channel = channel; open fun shouldSendTo(sender: CommandSender): Boolean {
this.message = message; return channel.shouldSendTo(sender, score)
this.score = score;
this.groupID = groupID;
}
/**
* Note: Errors are sent to the sender automatically
*/
public boolean shouldSendTo(CommandSender sender) {
return channel.shouldSendTo(sender, score);
}
/**
* Note: Errors are sent to the sender automatically
*/
public int getMCScore(CommandSender sender) {
return channel.getMCScore(sender);
} }
/** /**
* Note: Errors are sent to the sender automatically<br> * Note: Errors are sent to the sender automatically
*/
open fun getMCScore(sender: CommandSender): Int {
return channel.getMCScore(sender)
}
/**
* Note: Errors are sent to the sender automatically<br></br>
* *
* Null means don't send * Null means don't send
*/ */
@Nullable open fun getGroupID(sender: CommandSender): String? {
public String getGroupID(CommandSender sender) { return channel.getGroupID(sender)
return channel.getGroupID(sender);
} }
override fun isCancelled(): Boolean = isCancelled
override fun setCancelled(cancel: Boolean) = run { isCancelled = cancel }
} }

View file

@ -1,44 +1,29 @@
package buttondevteam.lib; package buttondevteam.lib
import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.Channel
import lombok.Getter; import org.bukkit.command.CommandSender
import lombok.Setter; import org.bukkit.event.Cancellable
import org.bukkit.command.CommandSender; import org.bukkit.event.Event
import org.bukkit.event.Cancellable; import org.bukkit.event.HandlerList
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/** /**
* Can be used to change messages before it's sent. * Can be used to change messages before it's sent.
* <b>Only called before sending messages with SendChatMessage.</b> * **Only called before sending messages with SendChatMessage.**
* *
* @author NorbiPeti * @author NorbiPeti
*
*/ */
@Getter class TBMCChatPreprocessEvent(val sender: CommandSender, val channel: Channel, var message: String) : Event(true),
public class TBMCChatPreprocessEvent extends Event implements Cancellable { Cancellable {
private static final HandlerList handlers = new HandlerList(); private var cancelled = false
override fun getHandlers(): HandlerList {
return handlerList
}
private final Channel channel; override fun isCancelled() = cancelled
private final CommandSender sender;
@Setter
private String message;
@Setter
private boolean cancelled;
public TBMCChatPreprocessEvent(CommandSender sender, Channel channel, String message) { override fun setCancelled(cancelled: Boolean) = run { this.cancelled = cancelled }
super(true);
this.sender = sender;
this.channel = channel;
this.message = message;
}
@Override companion object {
public HandlerList getHandlers() { val handlerList = HandlerList()
return handlers; }
}
public static HandlerList getHandlerList() {
return handlers;
}
} }

View file

@ -1,39 +1,33 @@
package buttondevteam.lib; package buttondevteam.lib
import buttondevteam.core.component.channel.Channel; import buttondevteam.core.component.channel.Channel
import lombok.Getter; import org.bukkit.command.CommandSender
import lombok.RequiredArgsConstructor; import org.bukkit.event.Cancellable
import lombok.Setter; import org.bukkit.event.Event
import org.bukkit.command.CommandSender; import org.bukkit.event.HandlerList
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
/** /**
* Can be used to change or handle commands before they're sent. * Can be used to change or handle commands before they're sent.
* <b>Called on using player, console and Discord commands.</b> * **Called on using player, console and Discord commands.**
* *
* @author NorbiPeti * @author NorbiPeti
*/ */
@Getter class TBMCCommandPreprocessEvent(
@RequiredArgsConstructor val sender: CommandSender,
public class TBMCCommandPreprocessEvent extends Event implements Cancellable { val channel: Channel,
private static final HandlerList handlers = new HandlerList(); val message: String,
val permCheck: CommandSender
) : Event(), Cancellable {
private var cancelled = false
override fun getHandlers(): HandlerList {
return handlerList
}
private final CommandSender sender; override fun isCancelled() = cancelled
private final Channel channel;
@Setter
private final String message;
private final CommandSender permCheck;
@Setter
private boolean cancelled;
@Override override fun setCancelled(cancelled: Boolean) = run { this.cancelled = cancelled }
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() { companion object {
return handlers; val handlerList = HandlerList()
} }
} }

View file

@ -1,43 +1,23 @@
package buttondevteam.lib; package buttondevteam.lib
import lombok.Getter; import org.bukkit.Bukkit
import org.bukkit.Bukkit; import org.bukkit.event.Event
import org.bukkit.event.Event; import org.bukkit.event.HandlerList
import org.bukkit.event.HandlerList;
/** /**
* <p> * This event gets called (ideally) each time an exception occurs in a TBMC plugin. To call it, use [TBMCCoreAPI.SendException].
* This event gets called (ideally) each time an exception occurs in a TBMC plugin. To call it, use {@link TBMCCoreAPI#SendException(String, Throwable)}. *
* </p>
* *
* @author Norbi * @author Norbi
*
*/ */
@Getter class TBMCExceptionEvent(val sourceMessage: String, val exception: Throwable) : Event(!Bukkit.isPrimaryThread()) {
public class TBMCExceptionEvent extends Event { var isHandled = false
private static final HandlerList handlers = new HandlerList();
private final String sourceMessage; override fun getHandlers(): HandlerList {
private final Throwable exception; return handlerList
private boolean handled; }
@java.beans.ConstructorProperties({"sourceMessage", "exception"}) companion object {
public TBMCExceptionEvent(String sourceMessage, Throwable exception) { val handlerList = HandlerList()
super(!Bukkit.isPrimaryThread()); }
this.sourceMessage = sourceMessage;
this.exception = exception;
}
public void setHandled() {
handled = true;
}
@Override
public HandlerList getHandlers() {
return handlers;
}
public static HandlerList getHandlerList() {
return handlers;
}
} }

View file

@ -35,6 +35,7 @@ class IHaveConfig(
* @return The data object that can be used to get or set the value * @return The data object that can be used to get or set the value
</T> */ </T> */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@JvmOverloads
fun <T> getData( fun <T> getData(
path: String, path: String,
def: T, def: T,
@ -57,6 +58,7 @@ class IHaveConfig(
* @return The data object that can be used to get or set the value * @return The data object that can be used to get or set the value
</T> */ </T> */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@JvmOverloads
fun <T> getData( fun <T> getData(
path: String, path: String,
getter: Function<Any?, T>, getter: Function<Any?, T>,
@ -77,6 +79,7 @@ class IHaveConfig(
* @return The data object that can be used to get or set the value * @return The data object that can be used to get or set the value
</T> */ </T> */
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
@JvmOverloads
fun <T> getListData( fun <T> getListData(
path: String, path: String,
def: List<T>, def: List<T>,

View file

@ -1,30 +1,24 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat
import lombok.Getter; enum class Color(private val cname: String, val red: Int, val green: Int, val blue: Int) : TellrawSerializableEnum {
import lombok.RequiredArgsConstructor; Black("black", 0, 0, 0),
DarkBlue("dark_blue", 0, 0, 170),
DarkGreen("dark_green", 0, 170, 0),
DarkAqua("dark_aqua", 0, 170, 170),
DarkRed("dark_red", 170, 0, 0),
DarkPurple("dark_purple", 0, 170, 0),
Gold("gold", 255, 170, 0),
Gray("gray", 170, 170, 170),
DarkGray("dark_gray", 85, 85, 85),
Blue("blue", 85, 85, 255),
Green("green", 85, 255, 85),
Aqua("aqua", 85, 255, 255),
Red("red", 255, 85, 85),
LightPurple("light_purple", 255, 85, 255),
Yellow("yellow", 255, 255, 85),
White("white", 255, 255, 255);
@RequiredArgsConstructor override fun getName(): String {
@Getter return cname
public enum Color implements TellrawSerializableEnum { }
Black("black", 0, 0, 0),
DarkBlue("dark_blue", 0, 0, 170),
DarkGreen("dark_green", 0, 170, 0),
DarkAqua("dark_aqua", 0, 170, 170),
DarkRed("dark_red", 170, 0, 0),
DarkPurple("dark_purple", 0, 170, 0),
Gold("gold", 255, 170,0),
Gray("gray", 170, 170, 170),
DarkGray("dark_gray", 85, 85, 85),
Blue("blue", 85, 85, 255),
Green("green", 85, 255, 85),
Aqua("aqua", 85, 255, 255),
Red("red", 255, 85,85),
LightPurple("light_purple", 255, 85, 255),
Yellow("yellow", 255, 255, 85),
White("white", 255, 255, 255);
private final String name;
private final int red;
private final int green;
private final int blue;
} }

View file

@ -82,7 +82,9 @@ abstract class Command2<TC : ICommand2<TP>, TP : Command2Sender>(
* @param allSupplier The supplier of all possible values (ideally) * @param allSupplier The supplier of all possible values (ideally)
</T> */ </T> */
open fun <T> addParamConverter( open fun <T> addParamConverter(
cl: Class<T>, converter: Function<String, T?>, errormsg: String, cl: Class<T>,
converter: Function<String, T?>,
errormsg: String,
allSupplier: Supplier<Iterable<String>> allSupplier: Supplier<Iterable<String>>
) { ) {
paramConverters[cl] = ParamConverter(converter, errormsg, allSupplier) paramConverters[cl] = ParamConverter(converter, errormsg, allSupplier)

View file

@ -1,33 +1,41 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat
import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.ArgumentType
import com.mojang.brigadier.builder.ArgumentBuilder; import com.mojang.brigadier.builder.ArgumentBuilder
import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.SuggestionProvider
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor class CoreArgumentBuilder<S, T>(
public class CoreArgumentBuilder<S, T> extends ArgumentBuilder<S, CoreArgumentBuilder<S, T>> { private val name: String,
private final String name; private val type: ArgumentType<T>,
private final ArgumentType<T> type; private val optional: Boolean
private final boolean optional; ) : ArgumentBuilder<S, CoreArgumentBuilder<S, T>>() {
private SuggestionProvider<S> suggestionsProvider = null; private var suggestionsProvider: SuggestionProvider<S>? = null
fun suggests(provider: SuggestionProvider<S>): CoreArgumentBuilder<S, T> {
suggestionsProvider = provider
return this
}
public static <S, T> CoreArgumentBuilder<S, T> argument(String name, ArgumentType<T> type, boolean optional) { override fun getThis(): CoreArgumentBuilder<S, T> {
return new CoreArgumentBuilder<S, T>(name, type, optional); return this
} }
public CoreArgumentBuilder<S, T> suggests(SuggestionProvider<S> provider) { override fun build(): CoreArgumentCommandNode<S, T> {
this.suggestionsProvider = provider; return CoreArgumentCommandNode(
return this; name,
} type,
command,
requirement,
redirect,
redirectModifier,
isFork,
suggestionsProvider,
optional
)
}
@Override companion object {
protected CoreArgumentBuilder<S, T> getThis() { fun <S, T> argument(name: String, type: ArgumentType<T>, optional: Boolean): CoreArgumentBuilder<S, T> {
return this; return CoreArgumentBuilder(name, type, optional)
} }
}
@Override
public CoreArgumentCommandNode<S, T> build() {
return new CoreArgumentCommandNode<>(name, type, getCommand(), getRequirement(), getRedirect(), getRedirectModifier(), isFork(), suggestionsProvider, optional);
}
} }

View file

@ -1,110 +1,112 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat
import lombok.Getter; import buttondevteam.lib.chat.Command2.Subcommand
import lombok.val; import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.lang.reflect.Method; import java.util.*
import java.lang.reflect.Modifier; import java.util.function.Function
import java.util.function.Function;
/** /**
* This class is used as a base class for all the specific command implementations. * This class is used as a base class for all the specific command implementations.
* It primarily holds information about the command itself and how it should be run, ideally in a programmer-friendly way. * It primarily holds information about the command itself and how it should be run, ideally in a programmer-friendly way.
* Any inferred and processed information about this command will be stored in the command manager (Command2*). * Any inferred and processed information about this command will be stored in the command manager (Command2*).
* *
* @param <TP> The sender's type * @param TP The sender's type
*/ </TP> */
public abstract class ICommand2<TP extends Command2Sender> { abstract class ICommand2<TP : Command2Sender>(manager: Command2<*, TP>) {
/** /**
* Default handler for commands, can be used to copy the args too. * Default handler for commands, can be used to copy the args too.
* *
* @param sender The sender which ran the command * @param sender The sender which ran the command
* @return The success of the command * @return The success of the command
*/ */
@SuppressWarnings("unused") @Suppress("UNUSED_PARAMETER")
public boolean def(TP sender) { fun def(sender: TP): Boolean {
return false; return false
} }
/** /**
* Convenience method. Return with this. * Convenience method. Return with this.
* *
* @param sender The sender of the command * @param sender The sender of the command
* @param message The message to send to the sender * @param message The message to send to the sender
* @return Always true so that the usage isn't shown * @return Always true so that the usage isn't shown
*/ */
protected boolean respond(TP sender, String message) { protected fun respond(sender: TP, message: String): Boolean {
sender.sendMessage(message); sender.sendMessage(message)
return true; return true
} }
/** /**
* Return null to not add any help text, return an empty array to only print subcommands.<br> * Return null to not add any help text, return an empty array to only print subcommands.<br></br>
* By default, returns null if the Subcommand annotation is not present and returns an empty array if no help text can be found. * By default, returns null if the Subcommand annotation is not present and returns an empty array if no help text can be found.
* *
* @param method The method of the subcommand * @param method The method of the subcommand
* @return The help text, empty array or null * @return The help text, empty array or null
*/ */
public String[] getHelpText(Method method, Command2.Subcommand ann) { open fun getHelpText(method: Method, ann: Subcommand): Array<String> {
val cc = getClass().getAnnotation(CommandClass.class); val cc = javaClass.getAnnotation(CommandClass::class.java)
return ann.helpText().length != 0 || cc == null ? ann.helpText() : cc.helpText(); //If cc is null then it's empty array return if (ann.helpText.isNotEmpty() || cc == null) ann.helpText else cc.helpText //If cc is null then it's empty array
} }
private final String path; private val path: String
@Getter val manager: Command2<*, TP>
private final Command2<?, TP> manager; //TIL that if I use a raw type on a variable then none of the type args will work (including what's defined on a method, not on the type) open val commandPath: String
/**
* The command's path, or name if top-level command.<br></br>
* For example:<br></br>
* "u admin updateplugin" or "u" for the top level one<br></br>
* <u>The path must be lowercase!</u><br></br>
*
* @return The command path, *which is the command class name by default* (removing any "command" from it) - Change via the [CommandClass] annotation
*/
get() = path
public <T extends ICommand2<TP>> ICommand2(Command2<T, TP> manager) { init {
path = getcmdpath(); path = getcmdpath()
this.manager = manager; this.manager = manager
} }
/** open val commandPaths: Array<String>
* The command's path, or name if top-level command.<br> /**
* For example:<br> * All of the command's paths it will be invoked on. Does not include aliases or the default path.
* "u admin updateplugin" or "u" for the top level one<br> * Must be lowercase and must include the full path.
* <u>The path must be lowercase!</u><br> *
* * @return The full command paths that this command should be registered under in addition to the default one.
* @return The command path, <i>which is the command class name by default</i> (removing any "command" from it) - Change via the {@link CommandClass} annotation */
*/ get() =// TODO: Deal with this (used for channel IDs)
public String getCommandPath() { EMPTY_PATHS
return path;
}
private static final String[] EMPTY_PATHS = new String[0]; private fun getcmdpath(): String {
if (!javaClass.isAnnotationPresent(CommandClass::class.java)) throw RuntimeException(
"No @CommandClass annotation on command class " + javaClass.simpleName + "!"
)
val getFromClass = Function { cl: Class<*> ->
cl.simpleName.lowercase(Locale.getDefault()).replace("commandbase", "") // <-- ...
.replace("command", "")
}
var path = javaClass.getAnnotation(CommandClass::class.java).path
var prevpath = if (path.isEmpty()) getFromClass.apply(javaClass) else path.also { path = it }
var cl: Class<*>? = javaClass.superclass
while (cl != null && cl.getPackage().name != ICommand2MC::class.java.getPackage().name) {
//
var newpath: String
val ccann: CommandClass? = cl.getAnnotation(CommandClass::class.java)
if (ccann?.path.isNullOrEmpty() || ccann?.path == prevpath) {
if (ccann?.excludeFromPath ?: Modifier.isAbstract(cl.modifiers)) {
cl = cl.superclass
continue
}
newpath = getFromClass.apply(cl)
} else newpath = ccann!!.path
path = "$newpath $path"
prevpath = newpath
cl = cl.superclass
}
return path
}
/** companion object {
* All of the command's paths it will be invoked on. Does not include aliases or the default path. private val EMPTY_PATHS = emptyArray<String>()
* Must be lowercase and must include the full path. }
*
* @return The full command paths that this command should be registered under in addition to the default one.
*/
public String[] getCommandPaths() { // TODO: Deal with this (used for channel IDs)
return EMPTY_PATHS;
}
private String getcmdpath() {
if (!getClass().isAnnotationPresent(CommandClass.class))
throw new RuntimeException(
"No @CommandClass annotation on command class " + getClass().getSimpleName() + "!");
Function<Class<?>, String> getFromClass = cl -> cl.getSimpleName().toLowerCase().replace("commandbase", "") // <-- ...
.replace("command", "");
String path = getClass().getAnnotation(CommandClass.class).path(),
prevpath = path = path.length() == 0 ? getFromClass.apply(getClass()) : path;
for (Class<?> cl = getClass().getSuperclass(); cl != null
&& !cl.getPackage().getName().equals(ICommand2MC.class.getPackage().getName()); cl = cl
.getSuperclass()) { //
String newpath;
if (!cl.isAnnotationPresent(CommandClass.class)
|| (newpath = cl.getAnnotation(CommandClass.class).path()).length() == 0
|| newpath.equals(prevpath)) {
if ((Modifier.isAbstract(cl.getModifiers()) && !cl.isAnnotationPresent(CommandClass.class))
|| cl.getAnnotation(CommandClass.class).excludeFromPath()) // <--
continue;
newpath = getFromClass.apply(cl);
}
path = (prevpath = newpath) + " " + path;
}
return path;
}
} }

View file

@ -1,46 +1,36 @@
package buttondevteam.lib.chat; package buttondevteam.lib.chat
import buttondevteam.lib.architecture.ButtonPlugin; import buttondevteam.lib.architecture.ButtonPlugin
import buttondevteam.lib.architecture.Component; import buttondevteam.lib.architecture.ButtonPlugin.Companion.command2MC
import lombok.Getter; import buttondevteam.lib.architecture.Component
import javax.annotation.Nullable; abstract class ICommand2MC : ICommand2<Command2MCSender>(command2MC) {
private var _plugin: ButtonPlugin? = null
var plugin: ButtonPlugin
get() = _plugin ?: throw IllegalStateException("The command is not registered to a plugin!")
private set(value) {
if (_plugin != null) throw IllegalStateException("The command is already assigned to a plugin!")
_plugin = value
}
private var _component: Component<*>? = null
var component: Component<*>
get() = _component ?: throw IllegalStateException("The command is not registered to a component!")
private set(value) {
if (_component != null) throw IllegalStateException("The command is already assigned to a component!")
_component = value
}
@SuppressWarnings("JavadocReference") /**
public abstract class ICommand2MC extends ICommand2<Command2MCSender> { * Called from [buttondevteam.lib.architecture.Component.registerCommand] and [ButtonPlugin.registerCommand]
@Getter */
private ButtonPlugin plugin; fun registerToPlugin(plugin: ButtonPlugin) {
@Getter this.plugin = plugin
@Nullable }
private Component<?> component;
public ICommand2MC() { /**
super(ButtonPlugin.getCommand2MC()); * Called from [buttondevteam.lib.architecture.Component.registerCommand]
} */
fun registerToComponent(component: Component<*>) {
/** this.component = component
* Called from {@link buttondevteam.lib.architecture.Component#registerCommand(ICommand2MC)} and {@link ButtonPlugin#registerCommand(ICommand2MC)} }
*/
public void registerToPlugin(ButtonPlugin plugin) {
if (this.plugin == null)
this.plugin = plugin;
else
throw new IllegalStateException("The command is already assigned to a plugin!");
}
/**
* Called from {@link buttondevteam.lib.architecture.Component#registerCommand(ICommand2MC)}
*/
public void registerToComponent(Component<?> component) {
if (this.component == null)
this.component = component;
else
throw new IllegalStateException("The command is already assigned to a component!");
}
/*@Override
public <TX extends ICommand2<Command2MCSender>> void onRegister(Command2<TX, Command2MCSender> manager) {
super.onRegister(manager);
onRegister((Command2MC) manager); //If ICommand2 is inherited with the same type arg, this would fail but I don't want to add another type param to ICommand2
} //For example: class IOffender extends ICommand2<Command2MCSender>*/
} }

View file

@ -32,7 +32,7 @@ object TBMCChatAPI {
* @return The event cancelled state * @return The event cancelled state
*/ */
@JvmOverloads @JvmOverloads
fun SendChatMessage(cm: ChatMessage, channel: Channel = cm.user.channel.get()): Boolean { fun sendChatMessage(cm: ChatMessage, channel: Channel = cm.user.channel.get()): Boolean {
if (!channelList.contains(channel)) throw RuntimeException( if (!channelList.contains(channel)) throw RuntimeException(
"Channel " + channel.displayName.get() + " not registered!" "Channel " + channel.displayName.get() + " not registered!"
) )
@ -41,8 +41,7 @@ object TBMCChatAPI {
return true //Cancel sending if channel is disabled return true //Cancel sending if channel is disabled
} }
val task = Supplier { val task = Supplier {
val permcheck = cm.getPermCheck() val rtr = getScoreOrSendError(channel, cm.permCheck)
val rtr = getScoreOrSendError(channel, permcheck)
val score = rtr.score val score = rtr.score
if (score == Channel.SCORE_SEND_NOPE || rtr.groupID == null) return@Supplier true if (score == Channel.SCORE_SEND_NOPE || rtr.groupID == null) return@Supplier true
val eventPre = TBMCChatPreprocessEvent(cm.sender, channel, cm.message) val eventPre = TBMCChatPreprocessEvent(cm.sender, channel, cm.message)
@ -93,7 +92,7 @@ object TBMCChatAPI {
* @param channel A new [Channel] to register * @param channel A new [Channel] to register
*/ */
@JvmStatic @JvmStatic
fun RegisterChatChannel(channel: Channel) { fun registerChatChannel(channel: Channel) {
registerChannel(channel) registerChannel(channel)
} }
} }