chore: 多依存環境向けにビルド設定を変更
This commit is contained in:
parent
08a2470167
commit
ac7216788c
|
|
@ -31,7 +31,6 @@ dependencies {
|
||||||
|
|
||||||
compileOnly("org.postgresql:postgresql:42.7.8")
|
compileOnly("org.postgresql:postgresql:42.7.8")
|
||||||
compileOnly("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1")
|
compileOnly("org.jetbrains.kotlinx:kotlinx-datetime:0.7.1")
|
||||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
|
|
||||||
compileOnly("org.jetbrains.exposed:exposed-core:$exposedVersion")
|
compileOnly("org.jetbrains.exposed:exposed-core:$exposedVersion")
|
||||||
compileOnly("org.jetbrains.exposed:exposed-dao:$exposedVersion")
|
compileOnly("org.jetbrains.exposed:exposed-dao:$exposedVersion")
|
||||||
compileOnly("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
|
compileOnly("org.jetbrains.exposed:exposed-jdbc:$exposedVersion")
|
||||||
|
|
|
||||||
2
hcu-core
2
hcu-core
|
|
@ -1 +1 @@
|
||||||
Subproject commit 388d0df943f2b4a0232c1f4f55f1cecb2d372fca
|
Subproject commit 520a378cd5c3da6321305d07cc0b402b73292add
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
rootProject.name = "faction"
|
rootProject.name = "faction"
|
||||||
|
if (gradle.parent == null) {
|
||||||
includeBuild("hcu-core")
|
includeBuild("hcu-core")
|
||||||
includeBuild("hcu-core/kommand-lib")
|
includeBuild("hcu-core/kommand-lib")
|
||||||
includeBuild("hcu-core/kommand-lib/permits-lib")
|
includeBuild("hcu-core/kommand-lib/permits-lib")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import org.bukkit.plugin.java.JavaPlugin
|
||||||
import net.kyori.adventure.text.Component
|
import net.kyori.adventure.text.Component
|
||||||
import net.kyori.adventure.text.format.NamedTextColor
|
import net.kyori.adventure.text.format.NamedTextColor
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
import net.hareworks.hcu.faction.service.FactionInfo
|
||||||
|
|
||||||
class FactionCommand(private val plugin: JavaPlugin, private val service: FactionService) {
|
class FactionCommand(private val plugin: JavaPlugin, private val service: FactionService) {
|
||||||
|
|
||||||
|
|
@ -22,6 +23,40 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
command("faction") {
|
command("faction") {
|
||||||
description = "Manage your faction"
|
description = "Manage your faction"
|
||||||
|
|
||||||
|
executes {
|
||||||
|
val sender = sender
|
||||||
|
if (sender !is Player) return@executes
|
||||||
|
|
||||||
|
val factionId = service.getFactionOfPlayer(sender.uniqueId)
|
||||||
|
if (factionId == null) {
|
||||||
|
sender.sendMessage(Component.text("You are not in a faction.", NamedTextColor.RED))
|
||||||
|
return@executes
|
||||||
|
}
|
||||||
|
|
||||||
|
val factionName = service.getFactionName(factionId)
|
||||||
|
if (factionName != null) {
|
||||||
|
displayFactionInfo(sender, factionName, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
literal("info") {
|
||||||
|
string("name") {
|
||||||
|
executes {
|
||||||
|
val sender = sender
|
||||||
|
val name = argument<String>("name")
|
||||||
|
displayFactionInfo(sender, name, 1)
|
||||||
|
}
|
||||||
|
integer("page") {
|
||||||
|
executes {
|
||||||
|
val sender = sender
|
||||||
|
val name = argument<String>("name")
|
||||||
|
val page = argument<Int>("page")
|
||||||
|
displayFactionInfo(sender, name, page)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
literal("create") {
|
literal("create") {
|
||||||
string("name") {
|
string("name") {
|
||||||
executes {
|
executes {
|
||||||
|
|
@ -44,12 +79,13 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
}
|
}
|
||||||
|
|
||||||
literal("invite") {
|
literal("invite") {
|
||||||
player("player") {
|
string("player") {
|
||||||
executes {
|
executes {
|
||||||
val sender = sender
|
val sender = sender
|
||||||
if (sender !is Player) return@executes
|
if (sender !is Player) return@executes
|
||||||
|
|
||||||
val target = argument<Player>("player")
|
val targetName = argument<String>("player")
|
||||||
|
val target = plugin.server.getOfflinePlayer(targetName)
|
||||||
|
|
||||||
val factionId = service.getFactionOfPlayer(sender.uniqueId)
|
val factionId = service.getFactionOfPlayer(sender.uniqueId)
|
||||||
if (factionId == null) {
|
if (factionId == null) {
|
||||||
|
|
@ -97,8 +133,6 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove join command
|
|
||||||
|
|
||||||
literal("accept") {
|
literal("accept") {
|
||||||
executes {
|
executes {
|
||||||
val sender = sender
|
val sender = sender
|
||||||
|
|
@ -124,30 +158,20 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
if (sender !is Player) return@executes
|
if (sender !is Player) return@executes
|
||||||
val targetName = argument<String>("target")
|
val targetName = argument<String>("target")
|
||||||
|
|
||||||
// Check if target is a Faction Name (Accepting Invite)
|
|
||||||
val factionIdByName = service.getFactionIdByName(targetName)
|
val factionIdByName = service.getFactionIdByName(targetName)
|
||||||
|
|
||||||
// Check if target is a Player Name (Accepting Join Request - Leader)
|
|
||||||
val factionIdOfSender = service.getFactionOfPlayer(sender.uniqueId)
|
val factionIdOfSender = service.getFactionOfPlayer(sender.uniqueId)
|
||||||
var processedAsRequest = false
|
|
||||||
|
|
||||||
if (factionIdOfSender != null) {
|
if (factionIdOfSender != null) {
|
||||||
val role = service.getRole(factionIdOfSender, sender.uniqueId)
|
val role = service.getRole(factionIdOfSender, sender.uniqueId)
|
||||||
if (role != FactionRole.MEMBER && role != null) {
|
if (role != FactionRole.MEMBER && role != null) {
|
||||||
val targetPlayer = plugin.server.getOfflinePlayer(targetName)
|
val targetPlayer = plugin.server.getOfflinePlayer(targetName)
|
||||||
// Try request accept
|
|
||||||
// Use a simplified check or just try calling the service.
|
|
||||||
// Service returns error if no request found.
|
|
||||||
// But if we have ambiguity (Faction name == Player name), what to do?
|
|
||||||
// We prioritize Request if Sender is Leader? Or Invite?
|
|
||||||
// Let's try Request first if Leader.
|
|
||||||
|
|
||||||
service.acceptRequest(factionIdOfSender, targetPlayer.uniqueId)
|
service.acceptRequest(factionIdOfSender, targetPlayer.uniqueId)
|
||||||
.onSuccess {
|
.onSuccess {
|
||||||
sender.sendMessage(Component.text("Accepted join request from $targetName", NamedTextColor.GREEN))
|
sender.sendMessage(Component.text("Accepted join request from $targetName", NamedTextColor.GREEN))
|
||||||
return@executes
|
return@executes
|
||||||
}
|
}
|
||||||
// If failed (e.g. no request), proceed to check if it's a Faction Invite for ME.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,7 +181,6 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
sender.sendMessage(Component.text("You joined $targetName", NamedTextColor.GREEN))
|
sender.sendMessage(Component.text("You joined $targetName", NamedTextColor.GREEN))
|
||||||
}
|
}
|
||||||
.onFailure { err ->
|
.onFailure { err ->
|
||||||
// If we also failed request above, user might be confused.
|
|
||||||
sender.sendMessage(Component.text("Error: $err (or no request found from player)", NamedTextColor.RED))
|
sender.sendMessage(Component.text("Error: $err (or no request found from player)", NamedTextColor.RED))
|
||||||
}
|
}
|
||||||
return@executes
|
return@executes
|
||||||
|
|
@ -205,8 +228,9 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
literal("promote") {
|
literal("promote") {
|
||||||
player("player") {
|
string("player") {
|
||||||
executes {
|
executes {
|
||||||
val sender = sender
|
val sender = sender
|
||||||
if (sender !is Player) return@executes
|
if (sender !is Player) return@executes
|
||||||
|
|
@ -222,7 +246,8 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
return@executes
|
return@executes
|
||||||
}
|
}
|
||||||
|
|
||||||
val target = argument<Player>("player")
|
val targetName = argument<String>("player")
|
||||||
|
val target = plugin.server.getOfflinePlayer(targetName)
|
||||||
|
|
||||||
service.promote(factionId, target.uniqueId)
|
service.promote(factionId, target.uniqueId)
|
||||||
.onSuccess { sender.sendMessage(Component.text("Promoted ${target.name}", NamedTextColor.GREEN)) }
|
.onSuccess { sender.sendMessage(Component.text("Promoted ${target.name}", NamedTextColor.GREEN)) }
|
||||||
|
|
@ -232,7 +257,7 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
}
|
}
|
||||||
|
|
||||||
literal("demote") {
|
literal("demote") {
|
||||||
player("player") {
|
string("player") {
|
||||||
executes {
|
executes {
|
||||||
val sender = sender
|
val sender = sender
|
||||||
if (sender !is Player) return@executes
|
if (sender !is Player) return@executes
|
||||||
|
|
@ -248,7 +273,8 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
return@executes
|
return@executes
|
||||||
}
|
}
|
||||||
|
|
||||||
val target = argument<Player>("player")
|
val targetName = argument<String>("player")
|
||||||
|
val target = plugin.server.getOfflinePlayer(targetName)
|
||||||
|
|
||||||
service.demote(factionId, target.uniqueId)
|
service.demote(factionId, target.uniqueId)
|
||||||
.onSuccess { sender.sendMessage(Component.text("Demoted ${target.name}", NamedTextColor.GREEN)) }
|
.onSuccess { sender.sendMessage(Component.text("Demoted ${target.name}", NamedTextColor.GREEN)) }
|
||||||
|
|
@ -326,11 +352,12 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
}
|
}
|
||||||
|
|
||||||
literal("kick") {
|
literal("kick") {
|
||||||
player("player") {
|
string("player") {
|
||||||
executes {
|
executes {
|
||||||
val sender = sender
|
val sender = sender
|
||||||
if (sender !is Player) return@executes
|
if (sender !is Player) return@executes
|
||||||
val target = argument<Player>("player")
|
val targetName = argument<String>("player")
|
||||||
|
val target = plugin.server.getOfflinePlayer(targetName)
|
||||||
|
|
||||||
service.kickPlayer(sender.uniqueId, target.uniqueId)
|
service.kickPlayer(sender.uniqueId, target.uniqueId)
|
||||||
.onSuccess { sender.sendMessage(Component.text("Kicked ${target.name}", NamedTextColor.GREEN)) }
|
.onSuccess { sender.sendMessage(Component.text("Kicked ${target.name}", NamedTextColor.GREEN)) }
|
||||||
|
|
@ -353,26 +380,102 @@ class FactionCommand(private val plugin: JavaPlugin, private val service: Factio
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
literal("info") {
|
private fun displayFactionInfo(sender: org.bukkit.command.CommandSender, factionName: String, page: Int) {
|
||||||
string("name") {
|
if (page < 1) {
|
||||||
executes {
|
sender.sendMessage(Component.text("Page must be 1 or higher.", NamedTextColor.RED))
|
||||||
val name = argument<String>("name")
|
return
|
||||||
val info = service.getFactionInfo(name)
|
}
|
||||||
|
val info = service.getFactionInfo(factionName)
|
||||||
if (info == null) {
|
if (info == null) {
|
||||||
sender.sendMessage(Component.text("Faction not found", NamedTextColor.RED))
|
sender.sendMessage(Component.text("Faction not found.", NamedTextColor.RED))
|
||||||
} else {
|
return
|
||||||
sender.sendMessage(Component.text("Faction: ${info.name}", NamedTextColor.GOLD))
|
|
||||||
sender.sendMessage(Component.text("Tag: ${info.tag ?: "None"}", NamedTextColor.WHITE))
|
|
||||||
sender.sendMessage(Component.text("Members: ${info.memberCount}", NamedTextColor.WHITE))
|
|
||||||
sender.sendMessage(Component.text("Open: ${info.open}", NamedTextColor.WHITE))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sender.sendMessage(Component.text("----- ${info.name} -----", NamedTextColor.GOLD))
|
||||||
|
sender.sendMessage(Component.text("Tag: ", NamedTextColor.GRAY).append(Component.text(info.tag ?: "None", NamedTextColor.WHITE)))
|
||||||
|
sender.sendMessage(Component.text("Owner: ", NamedTextColor.GRAY).append(Component.text(info.ownerName ?: "Unknown", NamedTextColor.WHITE)))
|
||||||
|
sender.sendMessage(Component.text("Members (${info.memberCount}):", NamedTextColor.GRAY))
|
||||||
|
|
||||||
|
val pageSize = 10
|
||||||
|
val members = service.getFactionMembers(info.id, page, pageSize)
|
||||||
|
|
||||||
|
if (members.isEmpty() && page > 1) {
|
||||||
|
sender.sendMessage(Component.text("No members on this page.", NamedTextColor.YELLOW))
|
||||||
|
}
|
||||||
|
|
||||||
|
val viewerId = (sender as? Player)?.uniqueId
|
||||||
|
val viewerFactionId = if (viewerId != null) service.getFactionOfPlayer(viewerId) else null
|
||||||
|
val viewerRole = if (viewerId != null && viewerFactionId == info.id) service.getRole(info.id, viewerId) else null
|
||||||
|
val isSameFaction = viewerFactionId == info.id
|
||||||
|
|
||||||
|
members.forEach { (uuid, name, role) ->
|
||||||
|
val roleColor = when (role) {
|
||||||
|
FactionRole.OWNER -> NamedTextColor.RED
|
||||||
|
FactionRole.EXEC -> NamedTextColor.GOLD
|
||||||
|
FactionRole.MEMBER -> NamedTextColor.GREEN
|
||||||
|
else -> NamedTextColor.WHITE
|
||||||
|
}
|
||||||
|
|
||||||
|
var line = Component.text("- ", NamedTextColor.DARK_GRAY)
|
||||||
|
.append(Component.text("[$role] ", roleColor))
|
||||||
|
.append(Component.text(name, NamedTextColor.WHITE))
|
||||||
|
|
||||||
|
if (isSameFaction && viewerRole != null && uuid != viewerId) {
|
||||||
|
// Add management buttons based on role
|
||||||
|
if (viewerRole == FactionRole.OWNER) {
|
||||||
|
// Owner can kick anyone (except self, handled by uuid check), promote member/demote exec, transfer
|
||||||
|
val kickBtn = Component.text(" [Kick]", NamedTextColor.RED)
|
||||||
|
.clickEvent(net.kyori.adventure.text.event.ClickEvent.runCommand("/faction kick $name"))
|
||||||
|
.hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text("Kick $name")))
|
||||||
|
line = line.append(kickBtn)
|
||||||
|
|
||||||
|
if (role == FactionRole.MEMBER) {
|
||||||
|
val promoteBtn = Component.text(" [Promote]", NamedTextColor.AQUA)
|
||||||
|
.clickEvent(net.kyori.adventure.text.event.ClickEvent.runCommand("/faction promote $name"))
|
||||||
|
.hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text("Promote to Exec")))
|
||||||
|
line = line.append(promoteBtn)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == FactionRole.EXEC) {
|
||||||
|
val demoteBtn = Component.text(" [Demote]", NamedTextColor.YELLOW)
|
||||||
|
.clickEvent(net.kyori.adventure.text.event.ClickEvent.runCommand("/faction demote $name"))
|
||||||
|
.hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text("Demote to Member")))
|
||||||
|
line = line.append(demoteBtn)
|
||||||
|
}
|
||||||
|
} else if (viewerRole == FactionRole.EXEC) {
|
||||||
|
// Exec can kick member
|
||||||
|
if (role == FactionRole.MEMBER) {
|
||||||
|
val kickBtn = Component.text(" [Kick]", NamedTextColor.RED)
|
||||||
|
.clickEvent(net.kyori.adventure.text.event.ClickEvent.runCommand("/faction kick $name"))
|
||||||
|
.hoverEvent(net.kyori.adventure.text.event.HoverEvent.showText(Component.text("Kick $name")))
|
||||||
|
line = line.append(kickBtn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sender.sendMessage(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pagination footer
|
||||||
|
val totalPages = (info.memberCount + pageSize - 1) / pageSize
|
||||||
|
if (totalPages > 1) {
|
||||||
|
val prevPage = if (page > 1) page - 1 else 1
|
||||||
|
val nextPage = if (page < totalPages) page + 1 else totalPages
|
||||||
|
|
||||||
|
val nav = Component.text("Page $page/$totalPages ", NamedTextColor.GRAY)
|
||||||
|
if (page > 1) {
|
||||||
|
nav.append(Component.text("[<]", NamedTextColor.AQUA)
|
||||||
|
.clickEvent(net.kyori.adventure.text.event.ClickEvent.runCommand("/faction info ${info.name} $prevPage")))
|
||||||
|
}
|
||||||
|
nav.append(Component.text(" "))
|
||||||
|
if (page < totalPages) {
|
||||||
|
nav.append(Component.text("[>]", NamedTextColor.AQUA)
|
||||||
|
.clickEvent(net.kyori.adventure.text.event.ClickEvent.runCommand("/faction info ${info.name} $nextPage")))
|
||||||
|
}
|
||||||
|
sender.sendMessage(nav)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -379,6 +379,24 @@ class FactionService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getFactionMembers(factionId: Int, page: Int, pageSize: Int = 10): List<Triple<UUID, String, FactionRole>> {
|
||||||
|
return DatabaseSessionManager.transaction {
|
||||||
|
(FactionMembersTable innerJoin PlayersTable)
|
||||||
|
.selectAll()
|
||||||
|
.andWhere { FactionMembersTable.factionId eq factionId }
|
||||||
|
.sortedBy { it[FactionMembersTable.role] } // Sort in-memory to avoid import issues
|
||||||
|
.drop((page - 1) * pageSize)
|
||||||
|
.take(pageSize)
|
||||||
|
.map {
|
||||||
|
Triple(
|
||||||
|
it[PlayersTable.uuid],
|
||||||
|
it[PlayersTable.username],
|
||||||
|
it[FactionMembersTable.role]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getFactionInfo(name: String): FactionInfo? {
|
fun getFactionInfo(name: String): FactionInfo? {
|
||||||
return DatabaseSessionManager.transaction {
|
return DatabaseSessionManager.transaction {
|
||||||
val row = FactionsTable.selectAll().andWhere { FactionsTable.name eq name }.singleOrNull() ?: return@transaction null
|
val row = FactionsTable.selectAll().andWhere { FactionsTable.name eq name }.singleOrNull() ?: return@transaction null
|
||||||
|
|
@ -389,24 +407,35 @@ class FactionService {
|
||||||
.andWhere { FactionMembersTable.role eq FactionRole.OWNER }
|
.andWhere { FactionMembersTable.role eq FactionRole.OWNER }
|
||||||
.singleOrNull()?.get(FactionMembersTable.playerUuid)
|
.singleOrNull()?.get(FactionMembersTable.playerUuid)
|
||||||
|
|
||||||
|
// Get owner name
|
||||||
|
val ownerName = ownerUuid?.let { uuid ->
|
||||||
|
PlayersTable.selectAll().andWhere { PlayersTable.uuid eq uuid }.singleOrNull()?.get(PlayersTable.username)
|
||||||
|
}
|
||||||
|
|
||||||
FactionInfo(
|
FactionInfo(
|
||||||
|
id,
|
||||||
row[FactionsTable.name],
|
row[FactionsTable.name],
|
||||||
row[FactionsTable.tag],
|
row[FactionsTable.tag],
|
||||||
row[FactionsTable.color],
|
row[FactionsTable.color],
|
||||||
|
row[FactionsTable.description],
|
||||||
row[FactionsTable.open],
|
row[FactionsTable.open],
|
||||||
count,
|
count,
|
||||||
ownerUuid
|
ownerUuid,
|
||||||
|
ownerName
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FactionInfo(
|
data class FactionInfo(
|
||||||
|
val id: Int,
|
||||||
val name: String,
|
val name: String,
|
||||||
val tag: String?,
|
val tag: String?,
|
||||||
val color: String?,
|
val color: String?,
|
||||||
|
val description: String?,
|
||||||
val open: Boolean,
|
val open: Boolean,
|
||||||
val memberCount: Long,
|
val memberCount: Long,
|
||||||
val owner: UUID?
|
val owner: UUID?,
|
||||||
|
val ownerName: String?
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user