diff --git a/scripts/coreMindustry/contentsTweaker.kts b/scripts/coreMindustry/contentsTweaker.kts index ff8a4e7..dd67fef 100644 --- a/scripts/coreMindustry/contentsTweaker.kts +++ b/scripts/coreMindustry/contentsTweaker.kts @@ -1,58 +1,30 @@ @file:Import("https://www.jitpack.io/", mavenRepository = true) -@file:Import("com.github.way-zer:ContentsTweaker:v3.1.2", mavenDependsSingle = true) +@file:Depends("coreMindustry/menu", "调用菜单") package coreMindustry -import cf.wayzer.contentsTweaker.ContentsTweaker -import mindustry.gen.Iconc - -var patches: String? - get() = state.map.tags.get("ContentsPatch") - set(v) { - state.map.tags.put("ContentsPatch", v) - //back compatibility - state.rules.tags.put("ContentsPatch", v!!) - } -var patchList: List - get() = patches?.split(";").orEmpty() - set(v) { - patches = v.joinToString(";") - } - -val ctPlayers = mutableMapOf() - -class CTHello(val player: Player, val version: String) : Event { - companion object : Event.Handler() -} - -registerVar("scoreboard.ext.contents-0-Version", "ContentsTweaker状态显示", DynamicVar { - if (patches == null) return@DynamicVar null - "{cK}CT修改已加载: {cV}{count} 修改".with("count" to patchList.size) -}) -registerVar("scoreboard.ext.contents-1-Advice", "ContentsTweaker未安装警告", DynamicVar { - if (patches == null) return@DynamicVar null - val player = VarToken("receiver").get() as? Player - if (player == null || player.uuid() !in ctPlayers) null - else "{cA}(使用ContentsTweakerMOD获得最佳体验)".with() -}) -registerVarForType().apply { - registerChild("suffix.s3-CT", "CT mod 后缀", { p -> Iconc.wrench.takeIf { p.uuid() in ctPlayers } }) -} - -fun sendPatch(name: String, patch: String) { - Call.clientPacketReliable("ContentsLoader|newPatch", "$name\n$patch") -} +import arc.struct.Seq +import arc.util.serialization.Jval +import mindustry.mod.ContentPatcher.PatchSet @JvmName("addPatchV3") -fun addPatch(name: String, patch: String) { - if (!name.startsWith("$")) { - state.map.tags.put("CT@$name", patch) - patchList = patchList.toMutableList().apply { - remove(name); add(name)//put last +fun addPatch(name: String, patch: String = "PatchFromContentsTweaker") { + val raw = patch + .replace("+=", "+") + .replace("#", "arg") + .replace(Regex("""(:)([\u4e00-\u9fa5][^,\}\]]*)""")) { m -> + val sep = m.groupValues[1] + val text = m.groupValues[2].trim() + "$sep\"$text\"" } - } - ContentsTweaker.loadPatch(name, patch) - sendPatch(name, patch) + .replace(Regex("(?<=\\{|,|\\s)([a-zA-Z0-9_-]+):"), "\"$1\":") + .replace(Regex(":\\s*([a-zA-Z_-]+)(?=\\s*[},])")) { m -> + ":\"${m.groupValues[1]}\"" + } + + val readPatch = Jval.read(raw).apply { asObject(); put("name", Jval.valueOf(name)) }.toString(Jval.Jformat.plain) + logger.info(readPatch) + state.patcher.apply(state.patcher.patches.map { it.patch }.add(readPatch)) } @JvmName("addPatch") fun addPatchOld(name: String, patch: String): String { @@ -61,43 +33,69 @@ fun addPatchOld(name: String, patch: String): String { } export(::addPatch) listen { - ContentsTweaker.recoverAll() - ctPlayers.clear() -} - -listen { - ctPlayers.remove(it.player.uuid()) + state.patcher.apply(Seq())//may load server global patches } listen { - if (ContentsTweaker.worldInReset) return@listen - var needAfterHandle = false state.map.tags.get("ContentsPatch")?.split(";")?.forEach { name -> if (name.isBlank()) return@forEach val patch = state.map.tags.get("CT@$name") ?: return@forEach - ContentsTweaker.loadPatch(name, patch, doAfter = false) - needAfterHandle = true + addPatch(name, patch) } - if (needAfterHandle) ContentsTweaker.afterHandle() } -//处理客户端请求 -onEnable { - netServer.addPacketHandler("ContentsLoader|version") { p, msg -> - logger.info("${p.name} $msg") - if (msg.contains("2.")) - Call.sendMessage(p.con, "你当前安装的CT版本过老,请更新到3.0.1", null, null) - ctPlayers[p.uuid()] = msg - launch(Dispatchers.game) { - CTHello(p, msg).emitAsync() - } - } - netServer.addPacketHandler("ContentsLoader|requestPatch") { p, msg -> - state.map.tags["CT@$msg"]?.let { sendPatch(msg, it) } +command("cp", "查看cp修改") { + type = CommandType.Client + body { + menu(player!!) } } -onDisable { - netServer.getPacketHandlers("ContentsLoader|version").clear() - netServer.getPacketHandlers("ContentsLoader|requestPatch").clear() -} \ No newline at end of file +suspend fun menu(player: Player, select: Int = 1) { + object : PagedMenuBuilder(state.patcher.patches.toList(), selectedPage = select, 6) { + override suspend fun renderItem(item: PatchSet) { + option(if (item.name.isEmpty()) "" else item.name) { + moreMenu(player, selectedPage, item) + } + } + + override suspend fun build() { + title = "[yellow]ContentPatcher" + msg = """ + [sky]查询服务器patch列表 + """.trimIndent() + super.build() + } + }.sendTo(player, 20_000) +} + +suspend fun moreMenu(player: Player, select: Int, item: PatchSet) { + MenuBuilder(true){ + title = "[yellow]Patch详情" + val jsonFlat = try { + val jval = Jval.read(item.patch) + flater(jval) + } catch (e: Exception) { + "[red]解析失败" + } + msg = """ + [white]${jsonFlat} + """.trimIndent() + option ("[red]返回"){ + menu(player, select) + } + }.sendTo(player, 20_000) +} + +fun flater(jval: Jval, prefix: String = ""): String = buildString { + when { + jval.isObject -> jval.asObject().forEach { + val fullKey = if (prefix.isEmpty()) it.key else "$prefix.${it.key}" + append(flater(it.value, fullKey)) + } + jval.isArray -> jval.asArray().forEachIndexed { index, value -> + append(flater(value, "$prefix[$index]")) + } + else -> append("$prefix = $jval\n") + } +}