Skip to content
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

Create & List Commands #135

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
45ad34f
Started working on create & list commands.
dmccoystephenson Mar 2, 2023
e786123
Added unit tests for 'fief' package.
dmccoystephenson Mar 2, 2023
9014360
Added tests for FiefsCommand class.
dmccoystephenson Mar 2, 2023
74bebc9
Implemented the create & list commands.
dmccoystephenson Mar 2, 2023
9adfe1a
Modified message colors for create & list commands.
dmccoystephenson Mar 2, 2023
dc7ceac
Required players to be in a faction and not already be in a fief in o…
dmccoystephenson Mar 2, 2023
72e1aab
Made a message red.
dmccoystephenson Mar 5, 2023
bca28b9
Modified chatcolor formatting for messages.
dmccoystephenson Mar 5, 2023
b2f3e2c
Extended base command description in plugin.yml
dmccoystephenson Mar 10, 2023
ecc1974
Made mock plugin a class field in TestFiefsCommand.kt
dmccoystephenson Mar 10, 2023
bc56e81
Switched order of some arguments to assertEquals() in TestFief.kt
dmccoystephenson Mar 10, 2023
534e22c
Cast return value of onTabComplete() method in FiefCommand.kt to List…
dmccoystephenson Mar 10, 2023
b560da2
Removed FiefFactory.kt
dmccoystephenson Mar 12, 2023
c9b4c9a
Fixed onTabComplete methods.
dmccoystephenson Mar 12, 2023
a235cd1
Removed useless cast.
dmccoystephenson Mar 12, 2023
141bbd3
Switched over to using MfFactionId instead of UUID to track faction m…
dmccoystephenson Mar 12, 2023
37ba2fe
Modified message verification in TestFiefsCommand.kt
dmccoystephenson Mar 12, 2023
911b789
Added mfFactionId field in Fief.kt
dmccoystephenson Mar 12, 2023
fdbf004
Created the MfFiefId value class.
dmccoystephenson Mar 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/main/kotlin/com/dansplugins/fiefs/Fiefs.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package com.dansplugins.fiefs

import com.dansplugins.factionsystem.MedievalFactions
import com.dansplugins.fiefs.command.fiefs.FiefsCommand
import com.dansplugins.fiefs.fief.FiefFactory
import com.dansplugins.fiefs.fief.FiefRepository
import org.bstats.bukkit.Metrics
import org.bukkit.plugin.java.JavaPlugin

class Fiefs : JavaPlugin() {
lateinit var medievalFactions: MedievalFactions

val fiefRepository = FiefRepository(this)
val fiefFactory = FiefFactory(this)
dmccoystephenson marked this conversation as resolved.
Show resolved Hide resolved

override fun onEnable() {
saveDefaultConfig()
config.options().copyDefaults(true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package com.dansplugins.fiefs.command.fiefs

import com.dansplugins.fiefs.Fiefs
import com.dansplugins.fiefs.command.fiefs.create.FiefsCreateCommand
import com.dansplugins.fiefs.command.fiefs.help.FiefsHelpCommand
import com.dansplugins.fiefs.command.fiefs.list.FiefsListCommand
import org.bukkit.ChatColor.AQUA
import org.bukkit.ChatColor.GREEN
import org.bukkit.command.Command
Expand All @@ -11,14 +13,20 @@ import org.bukkit.command.TabCompleter

class FiefsCommand(private val plugin: Fiefs) : CommandExecutor, TabCompleter {
private val helpCommand = FiefsHelpCommand(plugin)
private val createCommand = FiefsCreateCommand(plugin)
private val listCommand = FiefsListCommand(plugin)

private val subcommands = listOf(
"help"
"help",
"create",
"list"
)

override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
return when (args.firstOrNull()?.lowercase()) {
"help" -> helpCommand.onCommand(sender, command, label, args.drop(1).toTypedArray())
"create" -> createCommand.onCommand(sender, command, label, args.drop(1).toTypedArray())
"list" -> listCommand.onCommand(sender, command, label, args.drop(1).toTypedArray())
else -> {
// send plugin information
sender.sendMessage("$AQUA" + "Fiefs v${plugin.description.version}")
Expand All @@ -37,11 +45,13 @@ class FiefsCommand(private val plugin: Fiefs) : CommandExecutor, TabCompleter {
command: Command,
alias: String,
args: Array<out String>
): List<String> {
): List<String>? {
dmccoystephenson marked this conversation as resolved.
Show resolved Hide resolved
return when (args.size) {
1 -> subcommands.filter { it.startsWith(args[0]) }.toMutableList()
else -> when(args.first().lowercase()) {
"help" -> helpCommand.onTabComplete(sender, command, alias, args.drop(1).toTypedArray())
"create" -> createCommand.onTabComplete(sender, command, alias, args.drop(1).toTypedArray())
"list" -> listCommand.onTabComplete(sender, command, alias, args.drop(1).toTypedArray())
else -> emptyList()
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.dansplugins.fiefs.command.fiefs.create

import com.dansplugins.fiefs.Fiefs
import org.bukkit.ChatColor
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter
import org.bukkit.entity.Player

class FiefsCreateCommand(private val plugin: Fiefs) : CommandExecutor, TabCompleter {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
if (sender !is Player) {
sender.sendMessage("This command can only be run by a player.")
renbinden marked this conversation as resolved.
Show resolved Hide resolved
return false
}
val name = args.firstOrNull()
if (name == null) {
sender.sendMessage("${ChatColor.RED}" + "Please specify a name for the fief.")
renbinden marked this conversation as resolved.
Show resolved Hide resolved
return false
}
if (plugin.fiefRepository.getFief(name) != null) {
sender.sendMessage("${ChatColor.RED}" + "A fief with that name already exists.")
return false
}

// player must be in a faction
val mfPlayer = plugin.medievalFactions.services.playerService.getPlayer(sender)
val faction = plugin.medievalFactions.services.factionService.getFaction(mfPlayer?.id ?: return false)
if (faction == null) {
sender.sendMessage("${ChatColor.RED}" + "You must be in a faction to create a fief.")
return false
}

// player must not be in a fief already
val playersFief = plugin.fiefRepository.getPlayersFief(sender.uniqueId)
if (playersFief != null) {
sender.sendMessage("${ChatColor.RED}" + "You're already in a fief. You must leave it first.")
return false
}

val newFief = plugin.fiefFactory.createFief(name, sender.uniqueId)
plugin.fiefRepository.addFief(newFief)
sender.sendMessage("${ChatColor.GREEN}" + "Fief created.")
return true
}

override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: Array<out String>
): MutableList<String>? {
return null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class FiefsHelpCommand(private val plugin: Fiefs) : CommandExecutor, TabComplete
// send list of commands
sender.sendMessage("${AQUA}=== Fiefs Commands ===")
sender.sendMessage("${AQUA}/fiefs help - Displays a list of useful commands.")
sender.sendMessage("${AQUA}/fiefs create <name> - Creates a fief.")
sender.sendMessage("${AQUA}/fiefs list - Lists all fiefs.")
return true
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.dansplugins.fiefs.command.fiefs.list

import com.dansplugins.fiefs.Fiefs
import org.bukkit.ChatColor
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter

class FiefsListCommand(private val plugin: Fiefs) : CommandExecutor, TabCompleter {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>): Boolean {
if (plugin.fiefRepository.getFiefs().isEmpty()) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming the fief repository will read these from the database, you may wish to be careful about threading - commands are run on the main thread, and database queries perform I/O which would cause lag spikes each time the command was run.
Additionally, I'd recommend adding another layer of abstraction in a fief service type thing (which contains any domain logic) so your command isn't interfacing directly with the database.

sender.sendMessage("${ChatColor.RED}" + "There are no fiefs.")
return false
}
sender.sendMessage("${ChatColor.AQUA}" + "=== Fiefs ===")
for (fief in plugin.fiefRepository.getFiefs()) {
sender.sendMessage("${ChatColor.AQUA}" + fief.getName())
}
return true
}

override fun onTabComplete(
sender: CommandSender,
command: Command,
alias: String,
args: Array<out String>
): MutableList<String>? {
return null
}

}
36 changes: 36 additions & 0 deletions src/main/kotlin/com/dansplugins/fiefs/fief/Fief.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.dansplugins.fiefs.fief

import java.util.UUID

class Fief(private val name: String, private val ownerUUID: UUID) {
private var uuid = UUID.randomUUID()
dmccoystephenson marked this conversation as resolved.
Show resolved Hide resolved
private var members: MutableList<UUID> = mutableListOf()

fun getId(): UUID {
return uuid
}

fun addMember(uuid: UUID) {
members.add(uuid)
}

fun removeMember(uuid: UUID) {
members.remove(uuid)
}

fun isMember(uuid: UUID): Boolean {
return members.contains(uuid) || ownerUUID == uuid
}

fun getMembers(): List<UUID> {
return members
}

fun getOwnerUUID(): UUID {
return ownerUUID
}

fun getName(): String {
return name
}
}
14 changes: 14 additions & 0 deletions src/main/kotlin/com/dansplugins/fiefs/fief/FiefFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.dansplugins.fiefs.fief

import com.dansplugins.fiefs.Fiefs
import com.dansplugins.fiefs.fief.Fief
import java.util.UUID

/**
* Creates instances of the Fief class.
*/
class FiefFactory(private val plugin: Fiefs) {
fun createFief(name: String, ownerUUID: UUID): Fief {
return Fief(name, ownerUUID)
}
}
78 changes: 78 additions & 0 deletions src/main/kotlin/com/dansplugins/fiefs/fief/FiefRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.dansplugins.fiefs.fief

import com.dansplugins.fiefs.Fiefs
import java.util.*

/**
* Stores all Fiefs in a list and provides methods for accessing and modifying the list.
*/
class FiefRepository(private val plugin: Fiefs) {
private val fiefs = mutableListOf<Fief>()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume eventually this will be backed by a DB, negating the need for the list in the repository, but this is fine for testing purposes.


/**
* Adds a Fief to the list.
* @param fief The Fief to add.
*/
fun addFief(fief: Fief) {
fiefs.add(fief)
}

/**
* Removes a Fief from the list.
* @param fief The Fief to remove.
*/
fun removeFief(fief: Fief) {
fiefs.remove(fief)
}

/**
* Gets a Fief from the list.
* @param name The name of the Fief to get.
* @return The Fief with the given name.
*/
fun getFief(name: String): Fief? {
for (fief in fiefs) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The more functional approach to this adds a good deal of brevity and is clearer in its intent imo:
return fiefs.single { it.name == name }

You can also use .equals(ignoreCase = true) if you want case insensitive comparisons.

Can multiple fiefs have the same name?

if (fief.getName() == name) {
return fief
}
}
return null
}

/**
* Gets a Fief from the list.
* @param uuid The UUID of the Fief to get.
* @return The Fief with the given UUID.
*/
fun getFief(uuid: UUID): Fief? {
for (fief in fiefs) {
if (fief.getId() == uuid) {
return fief
}
}
return null
}

/**
* Gets a player's fief from the list.
* @param playerUUID The UUID of the player whose fief to get.
* @return The Fief which the player is a member of.
* @return null if the player is not a member of any fief.
*/
fun getPlayersFief(playerUUID: UUID): Fief? {
dmccoystephenson marked this conversation as resolved.
Show resolved Hide resolved
for (fief in fiefs) {
if (fief.isMember(playerUUID)) {
return fief
}
}
return null
}

/**
* Gets a list of all Fiefs.
* @return A list of all Fiefs.
*/
fun getFiefs(): List<Fief> {
return fiefs
}
}
10 changes: 8 additions & 2 deletions src/main/resources/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,15 @@ description: An expansion for Medieval Factions that allows faction members to c
commands:
fiefs:
description: The main command for Fiefs.
renbinden marked this conversation as resolved.
Show resolved Hide resolved
usage: /fiefs
aliases: [fi]

permissions:
fiefs.help:
default: true
default: true
description: Allows the player to view the help menu.
fiefs.create:
default: true
description: Allows the player to create a fief.
fiefs.list:
default: true
description: Allows the player to view a list of all fiefs.
60 changes: 60 additions & 0 deletions src/test/kotlin/com/dansplugins/fiefs/command/TestFiefsCommand.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.dansplugins.fiefs.command

import com.dansplugins.fiefs.Fiefs
import com.dansplugins.fiefs.command.fiefs.FiefsCommand
import io.mockk.every
import io.mockk.mockk
import io.mockk.verify
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.junit.jupiter.api.Test

class TestFiefsCommand {

private fun createMockPlugin(): Fiefs {
val mockPlugin = mockk<Fiefs>() {
renbinden marked this conversation as resolved.
Show resolved Hide resolved
every { description.version } returns "1.0.0"
every { description.authors } returns listOf("Dan")
every { description.description } returns "A plugin about fiefs."
}
return mockPlugin
}

@Test
fun testFiefsCommandNoArguments() {
// prepare
val mockPlugin = createMockPlugin()
val mockSender = mockk<CommandSender>() {
every { sendMessage(any<String>()) } returns Unit
}
val mockCommand = mockk<Command>()
val args = emptyArray<String>()
val label = "fiefs"
val fiefsCommand = FiefsCommand(mockPlugin)

// execute
fiefsCommand.onCommand(mockSender, mockCommand, label, args)

// verify
verify { mockSender.sendMessage(any<String>()); }
dmccoystephenson marked this conversation as resolved.
Show resolved Hide resolved
}

@Test
fun testFiefsCommandHelpArgument() {
// prepare
val mockPlugin = createMockPlugin()
val mockSender = mockk<CommandSender>() {
every { sendMessage(any<String>()) } returns Unit
}
val mockCommand = mockk<Command>()
val args = arrayOf("help")
val label = "fiefs"
val fiefsCommand = FiefsCommand(mockPlugin)

// execute
fiefsCommand.onCommand(mockSender, mockCommand, label, args)

// verify
verify { mockSender.sendMessage(any<String>()); }
}
}
Loading