-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Miles Holder
committed
May 9, 2024
1 parent
b805cdf
commit df5a4ef
Showing
10 changed files
with
290 additions
and
117 deletions.
There are no files selected for viewing
32 changes: 32 additions & 0 deletions
32
...rc/main/kotlin/com/github/spigotbasics/core/command/parsed/arguments/BukkitRegistryArg.kt
This file contains 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,32 @@ | ||
package com.github.spigotbasics.core.command.parsed.arguments | ||
|
||
import org.bukkit.Bukkit | ||
import org.bukkit.Keyed | ||
import org.bukkit.NamespacedKey | ||
import org.bukkit.Registry | ||
import org.bukkit.command.CommandSender | ||
import java.util.stream.Collectors | ||
|
||
class BukkitRegistryArg<T : Keyed>(name: String, registryClass: Class<T>) : CommandArgument<T>(name) { | ||
private val registry: Registry<T> = Bukkit.getRegistry(registryClass) ?: error("$registryClass is not a bukkit registry type") | ||
|
||
override fun parse( | ||
sender: CommandSender, | ||
value: String, | ||
): T? { | ||
return if (value.isBlank()) null else registry.get(NamespacedKey.fromString(value) ?: return null) | ||
} | ||
|
||
override fun tabComplete( | ||
sender: CommandSender, | ||
typing: String, | ||
): List<String> { | ||
return registry.stream().map { entry -> | ||
val namespacedKeyed = entry.key | ||
if (namespacedKeyed.namespace == NamespacedKey.MINECRAFT) { | ||
return@map namespacedKeyed.key | ||
} | ||
return@map namespacedKeyed.toString() | ||
}.collect(Collectors.toList()) | ||
} | ||
} |
This file contains 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
This file contains 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 |
---|---|---|
@@ -1,9 +1,13 @@ | ||
| Command | Permission | | ||
|------------------------------|-----------------------| | ||
| `/enchant <enchant> [level]` | basics.enchant | | ||
| Command | Permission | | ||
|---------------------------------------|----------------------| | ||
| `/enchant <enchant> [level]` | basics.enchant | | ||
| `/enchant <target> <enchant> [level]` | basics.enchant.other | | ||
|
||
> [!NOTE] | ||
> Players additionally require enchantment-specific permissions: `basics.enchant.<enchantment>`. | ||
> [!NOTE] | ||
> Enchanting items with unsafe levels additionally requires permission `basics.enchant.unsafe`. | ||
> Enchanting items with unsafe levels additionally requires permission `basics.enchant.unsafe.level`. | ||
> [!NOTE] | ||
> Enchanting items with unsafe enchants additional requires permission `basics.enchant.unsafe.enchant` |
139 changes: 55 additions & 84 deletions
139
...hant/src/main/kotlin/com/github/spigotbasics/modules/basicsenchant/BasicsEnchantModule.kt
This file contains 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 |
---|---|---|
@@ -1,107 +1,78 @@ | ||
package com.github.spigotbasics.modules.basicsenchant | ||
|
||
import com.github.spigotbasics.core.command.common.BasicsCommandExecutor | ||
import com.github.spigotbasics.core.command.common.CommandResult | ||
import com.github.spigotbasics.core.command.raw.RawCommandContext | ||
import com.github.spigotbasics.core.extensions.partialMatches | ||
import com.github.spigotbasics.core.extensions.toHumanReadable | ||
import com.github.spigotbasics.core.command.parsed.arguments.BukkitRegistryArg | ||
import com.github.spigotbasics.core.command.parsed.arguments.IntRangeArg | ||
import com.github.spigotbasics.core.command.parsed.arguments.SelectorMultiEntityArg | ||
import com.github.spigotbasics.core.command.parsed.arguments.SelectorSinglePlayerArg | ||
import com.github.spigotbasics.core.config.ConfigName | ||
import com.github.spigotbasics.core.module.AbstractBasicsModule | ||
import com.github.spigotbasics.core.module.loader.ModuleInstantiationContext | ||
import org.bukkit.Bukkit | ||
import com.github.spigotbasics.modules.basicsenchant.command.EnchantmentCommandOther | ||
import com.github.spigotbasics.modules.basicsenchant.command.EnchantmentCommandSelf | ||
import org.bukkit.enchantments.Enchantment | ||
import org.bukkit.entity.Player | ||
|
||
class BasicsEnchantModule(context: ModuleInstantiationContext) : AbstractBasicsModule(context) { | ||
val permission = | ||
private val commandPermission = | ||
permissionManager.createSimplePermission("basics.enchant", "Allows players access to the /enchant command") | ||
private val commandOtherPermission = permissionManager.createSimplePermission( | ||
"basics.enchant.other", | ||
"Allows players access to the /enchant command to enchant others" | ||
) | ||
val unsafeLevelsPermission = | ||
permissionManager.createSimplePermission( | ||
"basics.enchant", | ||
"Allows the player to enchant items", | ||
"basics.enchant.unsafe.level", | ||
"Allows assignment of unsafe levels for enchantments", | ||
) | ||
|
||
val permissionUnsafeLevels = | ||
val unsafeEnchantPermission = | ||
permissionManager.createSimplePermission( | ||
"basics.enchant.allowunsafe", | ||
"Allows the player to enchant items with unsafe levels", | ||
"basics.enchant.unsafe.enchant", | ||
"Allows assignment of unsafe enchantments to item", | ||
) | ||
|
||
val enchantments = Bukkit.getRegistry(Enchantment::class.java)?.map { it.key.key.lowercase() }?.toList() ?: emptyList() | ||
|
||
val enchantmentPermissions = | ||
Bukkit.getRegistry(Enchantment::class.java)?.associateWith { enchantment -> | ||
val name = enchantment.key.key.lowercase() | ||
permissionManager.createSimplePermission( | ||
"basics.enchant.$name", | ||
"Allows the player to enchant items with the ${name.toHumanReadable()} enchantment", | ||
) | ||
} ?: emptyMap() | ||
|
||
fun msgEnchantedSelf(tag: EnchantOperationMessageTag) = messages.getMessage("enchanted-self").tags(tag) | ||
|
||
// TODO: Cannot enchant others stuff yet | ||
fun msgEnchantedOthers( | ||
tag: EnchantOperationMessageTag, | ||
player: Player, | ||
) = messages.getMessage("enchanted-others") | ||
.tags(tag) | ||
.concerns(player) | ||
|
||
fun msgRemovedSelf(tag: EnchantOperationMessageTag) = messages.getMessage("removed-self").tags(tag) | ||
override val messages: Messages = getConfig(ConfigName.MESSAGES, Messages::class.java) | ||
|
||
override fun onEnable() { | ||
commandFactory.rawCommandBuilder("enchant", permission) | ||
.description("Enchants the item in the player's hand") | ||
.usage("<enchantment> [level]") | ||
.executor(EnchantExecutor()) | ||
.register() | ||
} | ||
|
||
inner class EnchantExecutor : BasicsCommandExecutor(this@BasicsEnchantModule) { | ||
override fun execute(context: RawCommandContext): CommandResult { | ||
val player = requirePlayerOrMustSpecifyPlayerFromConsole(context.sender) // TODO: Create a requirePlayer(Sender) method | ||
val args = context.args | ||
if (args.size == 0) return CommandResult.USAGE | ||
val item = requireItemInHand(player) | ||
val enchantment = getEnchantment(args[0]) ?: throw failInvalidArgument(args[0]).asException() | ||
var desiredLevel = (item.itemMeta?.getEnchantLevel(enchantment) ?: 0) + 1 | ||
val maxLevel = enchantment.maxLevel | ||
if (args.size > 1) { | ||
desiredLevel = args[1].toIntOrNull() ?: throw failInvalidArgument(args[1]).asException() | ||
val instance = this | ||
commandFactory.parsedCommandBuilder("enchant", commandPermission).mapContext { | ||
val basicExecutor = EnchantmentCommandSelf(instance) | ||
val otherExecutor = EnchantmentCommandOther(instance) | ||
usage = "<enchantment> [level]" | ||
path { | ||
playerOnly() | ||
arguments { | ||
named("enchantment", BukkitRegistryArg("enchantment", Enchantment::class.java)) | ||
} | ||
executor(basicExecutor) | ||
} | ||
|
||
// Unsafe levels require extra perm | ||
if (desiredLevel > maxLevel) { | ||
requirePermission(context.sender, permissionUnsafeLevels) | ||
path { | ||
playerOnly() | ||
arguments { | ||
named("enchantment", BukkitRegistryArg("enchantment", Enchantment::class.java)) | ||
named("level", IntRangeArg("level", { 0 }, { 255 })) | ||
executor(basicExecutor) | ||
} | ||
} | ||
|
||
// Enchantment-specific permissions | ||
enchantmentPermissions[enchantment]?.let { requirePermission(context.sender, it) } | ||
|
||
val tag = EnchantOperationMessageTag(item, enchantment, desiredLevel) | ||
|
||
if (desiredLevel == 0) { | ||
item.removeEnchantment(enchantment) // TODO: message "removed enchantment" | ||
msgRemovedSelf(tag).sendToPlayer(player) | ||
return CommandResult.SUCCESS | ||
path { | ||
permissions(commandOtherPermission) | ||
arguments { | ||
named("targets", SelectorMultiEntityArg("targets")) | ||
named("enchantment", BukkitRegistryArg("enchantment", Enchantment::class.java)) | ||
named("level", IntRangeArg("level", { 0 }, { 255 })) | ||
executor(otherExecutor) | ||
} | ||
} | ||
|
||
item.addUnsafeEnchantment( | ||
enchantment, | ||
desiredLevel, | ||
) // TODO: Separate permission for unsafe enchants, separate permission for max-level and for enchantment type | ||
msgEnchantedSelf(tag).sendToPlayer(player) | ||
return CommandResult.SUCCESS | ||
} | ||
|
||
override fun tabComplete(context: RawCommandContext): List<String>? { | ||
val args = context.args | ||
if (args.size == 1) { | ||
return enchantments.partialMatches(args[0]) | ||
path { | ||
permissions(commandOtherPermission) | ||
arguments { | ||
named("player", SelectorSinglePlayerArg("player")) | ||
named("enchantment", BukkitRegistryArg("enchantment", Enchantment::class.java)) | ||
named("level", IntRangeArg("level", { 0 }, { 255 })) | ||
executor(otherExecutor) | ||
} | ||
} | ||
return null | ||
} | ||
|
||
private fun getEnchantment(name: String): Enchantment? { | ||
return Bukkit.getRegistry(Enchantment::class.java)?.match(name.lowercase()) | ||
} | ||
}.register() | ||
} | ||
} |
23 changes: 0 additions & 23 deletions
23
...c/main/kotlin/com/github/spigotbasics/modules/basicsenchant/EnchantOperationMessageTag.kt
This file was deleted.
Oops, something went wrong.
76 changes: 76 additions & 0 deletions
76
.../basics-enchant/src/main/kotlin/com/github/spigotbasics/modules/basicsenchant/Messages.kt
This file contains 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,76 @@ | ||
package com.github.spigotbasics.modules.basicsenchant | ||
|
||
import com.github.spigotbasics.core.config.ConfigInstantiationContext | ||
import com.github.spigotbasics.core.config.SavedConfig | ||
import com.github.spigotbasics.core.extensions.toHumanReadable | ||
import com.github.spigotbasics.core.extensions.toRoman | ||
import com.github.spigotbasics.core.messages.Message | ||
import org.bukkit.enchantments.Enchantment | ||
import org.bukkit.entity.LivingEntity | ||
import org.bukkit.entity.Player | ||
import org.bukkit.inventory.ItemStack | ||
|
||
class Messages(context: ConfigInstantiationContext) : SavedConfig(context) { | ||
fun enchantmentSelf( | ||
item: ItemStack, | ||
enchantment: Enchantment, | ||
level: Int, | ||
): Message = modifyEnchantMessage(getMessage("enchanted-self"), item, enchantment, level) | ||
|
||
fun enchantEntity( | ||
entity: LivingEntity, | ||
item: ItemStack, | ||
enchantment: Enchantment, | ||
level: Int, | ||
): Message = | ||
modifyEnchantMessage( | ||
getMessage("enchanted-entity"), | ||
item, | ||
enchantment, | ||
level, | ||
).tagParsed("entity", entity.type.key.key.toHumanReadable()) | ||
|
||
fun enchantPlayer( | ||
player: Player, | ||
item: ItemStack, | ||
enchantment: Enchantment, | ||
level: Int, | ||
): Message = modifyEnchantMessage(getMessage("enchanted-others"), item, enchantment, level).tagParsed("player", player.name) | ||
|
||
fun enchantInvalidCombinationSelf( | ||
item: ItemStack, | ||
enchantment: Enchantment, | ||
): Message = | ||
getMessage("enchanted-invalid-combination-self") | ||
.tagParsed("item", item.type.name.toHumanReadable()) | ||
.tagParsed("enchantment", enchantment.key.key.toHumanReadable()) | ||
|
||
fun enchantInvalidCombinationEntity( | ||
entity: LivingEntity, | ||
item: ItemStack, | ||
enchantment: Enchantment, | ||
): Message = | ||
getMessage("enchanted-invalid-combination-entity") | ||
.tagParsed("entity", entity.type.key.key.toHumanReadable()) | ||
.tagParsed("item", item.type.name.toHumanReadable()) | ||
.tagParsed("enchantment", enchantment.key.key.toHumanReadable()) | ||
|
||
fun enchantInvalidCombinationOther( | ||
item: ItemStack, | ||
enchantment: Enchantment, | ||
): Message = | ||
getMessage("enchanted-invalid-combination-others") | ||
.tagParsed("item", item.type.name.toHumanReadable()) | ||
.tagParsed("enchantment", enchantment.key.key.toHumanReadable()) | ||
|
||
private fun modifyEnchantMessage( | ||
message: Message, | ||
item: ItemStack, | ||
enchantment: Enchantment, | ||
level: Int, | ||
): Message = | ||
message.tagParsed("item", item.type.name.toHumanReadable()) | ||
.tagParsed("enchantment", enchantment.key.key.toHumanReadable()) | ||
.tagParsed("level", level.toString()) | ||
.tagUnparsed("roman-level", level.toRoman()) | ||
} |
66 changes: 66 additions & 0 deletions
66
...n/kotlin/com/github/spigotbasics/modules/basicsenchant/command/EnchantmentCommandOther.kt
This file contains 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,66 @@ | ||
package com.github.spigotbasics.modules.basicsenchant.command | ||
|
||
import com.github.spigotbasics.core.command.parsed.CommandContextExecutor | ||
import com.github.spigotbasics.core.command.parsed.context.MapContext | ||
import com.github.spigotbasics.core.messages.Message | ||
import com.github.spigotbasics.modules.basicsenchant.BasicsEnchantModule | ||
import org.bukkit.Material | ||
import org.bukkit.command.CommandSender | ||
import org.bukkit.enchantments.Enchantment | ||
import org.bukkit.entity.LivingEntity | ||
import org.bukkit.entity.Player | ||
|
||
class EnchantmentCommandOther(private val module: BasicsEnchantModule) : CommandContextExecutor<MapContext> { | ||
override fun execute( | ||
sender: CommandSender, | ||
context: MapContext, | ||
) { | ||
val targets = mutableListOf<LivingEntity>() | ||
if (context["targets"] is List<*>) { | ||
targets.addAll((context["targets"] as List<*>).filterIsInstance<LivingEntity>()) | ||
} else if (context["player"] is Player) { | ||
targets.add(context["player"] as LivingEntity) | ||
} | ||
|
||
val enchantment = context["enchantment"] as Enchantment | ||
val level = context["level"] as Int | ||
|
||
if (level > enchantment.maxLevel && !sender.hasPermission(module.unsafeLevelsPermission)) { | ||
module.coreMessages.invalidValueForArgument("level", level.toString()).concerns(sender as? Player).sendToSender(sender) | ||
return | ||
} | ||
|
||
targets.forEach { | ||
val equipment = it.equipment ?: return | ||
val item = equipment.itemInMainHand | ||
if (item.type == Material.AIR) { | ||
return@forEach | ||
} | ||
|
||
if (!enchantment.canEnchantItem(item) && sender.hasPermission(module.unsafeEnchantPermission)) { | ||
val message: Message = | ||
if (it is Player) { | ||
module.messages.enchantInvalidCombinationOther(item, enchantment).concerns(it) | ||
} else { | ||
module.messages.enchantInvalidCombinationEntity(it, item, enchantment) | ||
} | ||
message.sendToSender(sender) | ||
return | ||
} | ||
|
||
val meta = item.itemMeta!! | ||
meta.addEnchant(enchantment, level, sender.hasPermission(module.unsafeLevelsPermission)) | ||
item.itemMeta = meta | ||
equipment.setItemInMainHand(item) | ||
|
||
val message = | ||
if (it is Player) { | ||
module.messages.enchantPlayer(it, item, enchantment, level).concerns(it) | ||
} else { | ||
module.messages.enchantEntity(it, item, enchantment, level) | ||
} | ||
|
||
message.sendToSender(sender) | ||
} | ||
} | ||
} |
Oops, something went wrong.