package cc.maxmc.invite.command import cc.maxmc.invite.PluginScope import cc.maxmc.invite.concurrent.chatInput import cc.maxmc.invite.data.InviteCode import cc.maxmc.invite.data.InviteCodes import cc.maxmc.invite.listener.InvitedListener import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.bukkit.Bukkit import org.bukkit.command.ConsoleCommandSender import org.bukkit.entity.Player import org.jetbrains.exposed.sql.transactions.transaction import taboolib.common.platform.command.CommandBuilder import taboolib.common.platform.command.command import taboolib.common.platform.function.getDataFolder import taboolib.common.platform.function.info import java.io.File import java.text.SimpleDateFormat import java.util.* object InviteCodeCommands { init { command("inviteCode", aliases = listOf("code", "icode", "ic")) { cmdUse() cmdGenerate() cmdEdit() cmdAdd() cmdRemove() cmdCurrent() } } private fun CommandBuilder.CommandComponent.cmdUse() = literal("use") { tailrec suspend fun requireQQNumber(player: Player): String? { val input = chatInput(player, "§e| §7请输入您的QQ号进行绑定 (输入 §ecancel §7取消)") if (input == "cancel") return null if (input.length >= 10) return requireQQNumber(player) if (input.toLongOrNull() == null) return requireQQNumber(player) return input } dynamic { execute { sender, _, argument -> if (!InvitedListener.cache.containsKey(sender.uniqueId)) return@execute sender.sendMessage("§e| §7您的账号已激活, 无需使用邀请码.") sender.sendMessage("§b| §7正在激活邀请码...") PluginScope.launch { val inviteCode = transaction { val inviteCode = InviteCode.find { InviteCodes.inviteCode eq argument }.firstOrNull() ?: return@transaction let { sender.sendMessage("§c| §7该激活码不存在, 请重试."); null } if (inviteCode.name != null) return@transaction sender.sendMessage("§c| §7该邀请码已被激活, 请重试.") .let { null } return@transaction inviteCode } ?: return@launch val qqNum = requireQQNumber(sender) ?: return@launch sender.sendMessage("§e| §7已取消激活验证码.") sender.sendMessage("§a| §7该激活码成功绑定至QQ: §a${qqNum}") InvitedListener.cache.remove(sender.uniqueId) transaction { inviteCode.run { name = sender.name uid = sender.uniqueId qq = qqNum } sender.sendMessage("§a| §7成功激活邀请码.") } } } } } private fun CommandBuilder.CommandComponent.cmdGenerate() = literal("generate") { fun generateRandomString(length: Int): String { val availableChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890" val result = StringBuilder() repeat(length) { result.append(availableChars.random()) } return result.toString() } tailrec fun generateAvailableCode(): String { val result = "${generateRandomString(5)}-${generateRandomString(5)}-${generateRandomString(5)}-${ generateRandomString(5) }" val exist = transaction { val exist = !InviteCode.find { InviteCodes.inviteCode eq result }.empty() if (!exist) { InviteCode.new { inviteCode = result } } return@transaction exist } return if (exist) generateAvailableCode() else result } val format = SimpleDateFormat("yyyy-MM-dd") dynamic { restrict { _, _, arg -> return@restrict arg.toIntOrNull() != null } execute { _, _, arg -> PluginScope.launch { info("§b| §7正在生成邀请码...") val generated = ArrayList() repeat(arg.toInt()) { generated.add(generateAvailableCode()) } val generateFolder = File(getDataFolder(), "generated") generateFolder.mkdirs() val count = generateFolder.listFiles()!!.filter { it.name.startsWith(format.format(Date())) }.size val target = File(generateFolder, "${format.format(Date())}-${count + 1}.txt") withContext(Dispatchers.IO) { target.createNewFile() target.writeText(generated.joinToString("\n")) } info("§a| §7成功生成 §a$arg §7个邀请码") } } } } private fun CommandBuilder.CommandComponent.cmdEdit() = literal("edit") { dynamic { restrict { _, _, arg -> !InviteCode.find { InviteCodes.name eq arg }.empty() } suggestion { sender, ctx -> return@suggestion Bukkit.getOnlinePlayers().map { it.name } } dynamic { restrict { _, _, arg -> arg.length <= 10 && arg.toLongOrNull() != null } execute { sender, ctx, arg -> PluginScope.launch { InviteCode.find { InviteCodes.name eq ctx.get(-1) }.first().run { qq = arg } sender.sendMessage("§a| §7修改成功") } } } } } private fun CommandBuilder.CommandComponent.cmdAdd() = literal("add") { dynamic { execute { sender, _, arg -> PluginScope.launch { if (!InviteCode.find { InviteCodes.inviteCode eq arg }.empty()) { sender.sendMessage("§c| §7该邀请码已存在, 无法添加.") return@launch } InviteCode.new { inviteCode = arg } sender.sendMessage("§a| §7成功添加一个邀请码: §a$arg") } } } } private fun CommandBuilder.CommandComponent.cmdRemove() = literal("remove") { execute { sender, _, arg -> PluginScope.launch { transaction { val findings = InviteCode.find { InviteCodes.inviteCode eq arg } if (findings.empty()) { sender.sendMessage("§e| §7该邀请码不存在, 无需删除.") } findings.first().delete() sender.sendMessage("§a| §7成功删除该邀请码.") } } } } private fun CommandBuilder.CommandComponent.cmdCurrent() = literal("current") { execute { sender, _, _ -> PluginScope.launch { val codes = ArrayList(2000) transaction { InviteCode.find { InviteCodes.uid eq null }.forEach { codes.add(it.inviteCode) } } val result = codes.joinToString("\n") val output = File(getDataFolder(), "current.txt") withContext(Dispatchers.IO) { output.mkdirs() output.createNewFile() output.writeText(result) } sender.sendMessage("现存可用邀请码已保存至plugins/BiliInviteCode/current.txt") } } } }