Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
zly2006 committed Jul 12, 2024
1 parent 6ec5afc commit e8501af
Show file tree
Hide file tree
Showing 8 changed files with 946 additions and 827 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package com.github.zly2006.enclosure.command

import com.github.zly2006.enclosure.ServerMain
import com.github.zly2006.enclosure.access.PlayerAccess
import com.github.zly2006.enclosure.network.config.EnclosureInstalledC2SPacket
import com.github.zly2006.enclosure.utils.Permission
import com.github.zly2006.enclosure.utils.Serializable2Text.SerializationSettings
import com.github.zly2006.enclosure.utils.TrT
import com.github.zly2006.enclosure.utils.Utils
import com.github.zly2006.enclosure.utils.plus
import com.mojang.brigadier.arguments.StringArgumentType
import net.minecraft.command.argument.EntityArgumentType
import net.minecraft.text.ClickEvent
import net.minecraft.text.Text
import net.minecraft.util.math.BlockPos

fun BuilderScope<*>.registerAdmin() {
literal("admin") {
literal("reload") {
permission("enclosure.command.admin.reload", BuilderScope.Companion.DefaultPermission.OP)
literal("all") {
executes {
ServerMain.reloadCommon()
ServerMain.reloadLimits()
source.sendMessage(Text.literal("Reloaded, some config may not affect until restart"))
}
}
literal("common") {
executes {
ServerMain.reloadCommon()
source.sendMessage(Text.literal("Reloaded, some config may not affect until restart"))
}
}
literal("limits") {
executes {
ServerMain.reloadLimits()
source.sendMessage(Text.literal("Reloaded, some config may not affect until restart"))
}
}
}
literal("limit_exceeded") {
permission("enclosure.command.admin.limit_exceeded", BuilderScope.Companion.DefaultPermission.OP)
literal("size") {
executes {
ServerMain.getAllEnclosures().flatMap {
it.subEnclosures.areas.toList() + it
}.map {
val session = Session(null)
session.pos1 = BlockPos(it.minX, it.minY, it.minZ)
session.pos2 = BlockPos(it.maxX, it.maxY, it.maxZ)
it to session.isValid(getLimits(this))
}.filter { it.second != null }.forEach { (area, text) ->
source.sendMessage(
Text.literal("Enclosure ")
.append(area.serialize(SerializationSettings.Name, source.player))
.append(" is too large: ")
.append(text)
)
}
}
}
literal("count") {
executes {
ServerMain.getAllEnclosures().groupBy {
it.owner
}.forEach { (owner, enclosures) ->
if (enclosures.size > getLimits(this).maxLands) {
source.sendMessage(
Text.literal("Player ") +
Utils.getDisplayNameByUUID(owner) +
" has too many enclosures: " +
enclosures.size.toString()
)
}
}
}
}
}
literal("visited") {
permission("enclosure.command.admin.visited", BuilderScope.Companion.DefaultPermission.OP)
argument("player", EntityArgumentType.player()) {
literal("get") {
executes {
val player = EntityArgumentType.getPlayer(this, "player")
val visited = ServerMain.getAllEnclosures()
.filter { it.uuid in (player as PlayerAccess).visitedEnclosures }
val text = player.name.copy().append(" visited: ")
visited.forEach { e ->
text.append(e.serialize(SerializationSettings.Summarize, player))
.append(" ")
}
source.sendMessage(text)
}
}
literal("clear") {
executes {
val player = EntityArgumentType.getPlayer(this, "player")
(player as PlayerAccess).visitedEnclosures.clear()
source.sendMessage(Text.literal("Cleared"))
}
}
}
}
literal("closest") {
permission("enclosure.command.admin.closest", BuilderScope.Companion.DefaultPermission.OP)
executes {
val enclosure = ServerMain.getAllEnclosures(source.world).areas
.minByOrNull {
it.distanceTo(source.position).horizontalLength()
}
if (enclosure == null) {
source.sendMessage(Text.literal("No enclosure found"))
} else {
source.sendMessage(
Text.literal("Closest enclosure: " + enclosure.fullName + ", click to show info")
.styled {
it.withClickEvent(
ClickEvent(
net.minecraft.text.ClickEvent.Action.RUN_COMMAND,
"/enclosure info " + enclosure.fullName
)
)
})
}
}
}
literal("perm-info") {
permission("enclosure.command.admin.perm_info", BuilderScope.Companion.DefaultPermission.OP)
argument(permissionArgument(com.github.zly2006.enclosure.utils.Permission.Target.Both)) {
executes {
val permission = Permission.getValue(StringArgumentType.getString(this, "permission"))
?: error(TrT.of("enclosure.message.invalid_permission"), this)
source.sendMessage(
Text.literal("Name: ${permission.name} Target: ${permission.target}\nDescription: ") + permission.description + Text.literal(
"\nDefault: ${permission.defaultValue}\nComponents: ${permission.permissions.joinToString()}"
)
)
}
}
}
literal("clients") {
permission("enclosure.command.admin.clients", BuilderScope.Companion.DefaultPermission.OP)
executes {
EnclosureInstalledC2SPacket.installedClientMod.forEach {
source.sendMessage(
source.server.playerManager.getPlayer(it.key)!!.name.copy()
.append(Text.literal(": " + it.value.friendlyString))
)
}
}
}
}
}
191 changes: 191 additions & 0 deletions src/main/kotlin/com/github/zly2006/enclosure/command/BuilderScope.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package com.github.zly2006.enclosure.command

import com.github.zly2006.enclosure.EnclosureArea
import com.github.zly2006.enclosure.LOGGER
import com.github.zly2006.enclosure.ServerMain
import com.github.zly2006.enclosure.exceptions.PermissionTargetException
import com.github.zly2006.enclosure.minecraftServer
import com.github.zly2006.enclosure.utils.TrT
import com.github.zly2006.enclosure.utils.checkPermission
import com.github.zly2006.enclosure.utils.hoverText
import com.mojang.brigadier.Command
import com.mojang.brigadier.arguments.ArgumentType
import com.mojang.brigadier.arguments.IntegerArgumentType
import com.mojang.brigadier.builder.RequiredArgumentBuilder
import com.mojang.brigadier.context.CommandContext
import com.mojang.brigadier.exceptions.CommandSyntaxException
import net.minecraft.server.command.CommandManager
import net.minecraft.server.command.ServerCommandSource
import net.minecraft.text.*
import net.minecraft.util.Formatting
import net.minecraft.util.math.BlockPos

class BuilderScope<T: argT>(var parent: T) {
fun literal(name: String, action: BuilderScope<*>.() -> Unit) {
val node = CommandManager.literal(name)
BuilderScope(node).apply(action)
parent.then(node)
}

fun argument(name: String, type: ArgumentType<*>, action: BuilderScope<*>.() -> Unit) {
val node = CommandManager.argument(name, type)
argument(node, action)
}

fun argument(node: RequiredArgumentBuilder<ServerCommandSource, *>, action: BuilderScope<*>.() -> Unit) {
BuilderScope(node).apply(action)
parent.then(node)
}

fun executes(action: CommandContext<ServerCommandSource>.() -> Unit) {
parent.executes {
try {
action(it)
1
} catch (e: PermissionTargetException) {
error(e.text, it)
} catch (e: CommandSyntaxException) {
throw e
} catch (e: Exception) {
LOGGER.error("Error while executing command: " + it.input, e)
error(TrT.of("enclosure.message.error").append(e.message), it)
}
}
}

fun paged(commandSupplier: CommandContext<ServerCommandSource>.() -> String? = { null }, listSupplier: CommandContext<ServerCommandSource>.() -> List<Text>) {
val size = 5
val action: CommandContext<ServerCommandSource>.(Int) -> Unit = { p ->
val command = commandSupplier()
val list = listSupplier()
val totalPage: Int = (list.size + size - 1) / size
var page = p
if (p < 1 || p > totalPage) { // 如果选取页码超过范围限制,则采用第一页
page = 1
}
val firstPage = page == 1
val lastPage = page >= totalPage

val ret: MutableText = TrT.of("enclosure.menu.page.0")
.append(page.toString())
.append(TrT.of("enclosure.menu.page.1"))
.append(totalPage.toString())
.append("\n")

var i: Int = size * (page - 1)
while (i < size * page && i < list.size) {
ret.append(list[i])
ret.append("\n")
i++
}

if (command != null) {
ret.append(
TrT.of("enclosure.menu.previous").setStyle(
if (firstPage) Style.EMPTY.withColor(Formatting.GRAY)
else Style.EMPTY.withColor(Formatting.DARK_GREEN)
.hoverText(Text.of("Page ${page - 1}"))
.withClickEvent(ClickEvent(ClickEvent.Action.RUN_COMMAND, "$command ${page - 1}"))
)
)
ret.append(" ")
ret.append(
TrT.of("enclosure.menu.next").setStyle(
if (lastPage) Style.EMPTY.withColor(Formatting.GRAY)
else Style.EMPTY.withColor(Formatting.DARK_GREEN)
.withHoverEvent(HoverEvent(HoverEvent.Action.SHOW_TEXT, Text.of("Page ${page + 1}")))
.withClickEvent(ClickEvent(ClickEvent.Action.RUN_COMMAND, "$command ${page + 1}"))
)
)
}
source.sendMessage(ret)
}
executes { action(0) }
argument("page", IntegerArgumentType.integer(0)) {
executes {
action(IntegerArgumentType.getInteger(this, "page"))
}
}
}

/**
* @param action 传入参数表示是否包含[node]
*/
private fun optionalNode(node: argT, action: BuilderScope<*>.(Boolean) -> Unit) {
BuilderScope(node).apply { action(true) }
parent.then(node)
BuilderScope(parent).apply { action(false) }
}

fun optionalEnclosure(action: CommandContext<ServerCommandSource>.(EnclosureArea) -> Unit) {
optionalNode(landArgument()) {
executes {
if (it) {
val enclosure = getEnclosure(this)
action(enclosure)
} else {
val blockPos = BlockPos.ofFloored(source.position)
ServerMain.getSmallestEnclosure(source.world, blockPos)
?.let { action(it) }
?: error(TrT.of("enclosure.message.no_enclosure"), this)
}
}
}
}

fun optionalEnclosure(action: CommandContext<ServerCommandSource>.(EnclosureArea) -> Unit, builder: (argT, Command<ServerCommandSource>) -> Unit) {
optionalEnclosure(listOf(0), { _, c -> builder(parent, c) }) { a, _ -> action(a) }
}

fun <T: Any?> optionalEnclosure(list: List<T>, builder: BuilderScope<*>.(T, Command<ServerCommandSource>) -> Unit, action: CommandContext<ServerCommandSource>.(EnclosureArea, T) -> Unit) {
list.forEach { t ->
val node = landArgument()
BuilderScope(node).apply {
builder(t, Command {
val enclosure = getEnclosure(it)
it.action(enclosure, t)
1
})
}
BuilderScope(parent).apply {
builder(t, Command {
val blockPos = BlockPos.ofFloored(it.source.position)
ServerMain.getSmallestEnclosure(it.source.world, blockPos)
?.let { area -> action(it, area, t) }
?: error(TrT.of("enclosure.message.no_enclosure"), it)
1
})
}
parent.then(node)
}
}


companion object {
enum class DefaultPermission {
TRUE, FALSE, OP;

fun get(source: ServerCommandSource) =
when (this) {
TRUE -> true
FALSE -> false
OP -> source.hasPermissionLevel(
if (minecraftServer.isSingleplayer) 2 else 4 // 2 for LAN, 4 for normal
)
}
}

val map = mutableMapOf<String, DefaultPermission>(
"enclosure.bypass" to DefaultPermission.OP
)
}
fun permission(s: String, defaultPermission: DefaultPermission) {
val old = parent.requirement
if (!map.containsKey(s)) {
map[s] = defaultPermission
}
parent.requires { source ->
checkPermission(source, s) && old.test(source)
}
}
}
Loading

0 comments on commit e8501af

Please sign in to comment.