diff --git a/README.md b/README.md index eb9b5af..fae3fdb 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ * プレイヤーにformを表示する * プレイヤーを追放する * プレイヤーをkillする(クリエイティブモード含む) +* プレイヤーをノックバックする * プレイヤーのネームタグを変更する * プレイヤーのネームタグをリセットする * 複数のコマンドを実行する @@ -49,7 +50,6 @@ * 爆発を発生させる * エンティティをスポーンする * カスタムされたアイテムをスポーンする -* パーティクルをスポーンする * ワールド全体にメッセージを送信(say) * ディメンションを超えてプレイヤーをテレポートさせる ### Config diff --git a/functions/Capi_setup.mcfunction b/functions/Capi_setup.mcfunction index b60648d..8aac9be 100644 --- a/functions/Capi_setup.mcfunction +++ b/functions/Capi_setup.mcfunction @@ -53,5 +53,8 @@ scoreboard objectives add Capi:deathPlayer dummy scoreboard objectives add Capi:itemUseOnX dummy scoreboard objectives add Capi:itemUseOnY dummy scoreboard objectives add Capi:itemUseOnZ dummy +scoreboard objectives add Capi:vectorX dummy +scoreboard objectives add Capi:vectorY dummy +scoreboard objectives add Capi:vectorZ dummy gamerule sendcommandfeedback false gamerule commandblockoutput false \ No newline at end of file diff --git a/functions/Capi_version.mcfunction b/functions/Capi_version.mcfunction index fde1af5..8bc7c55 100644 --- a/functions/Capi_version.mcfunction +++ b/functions/Capi_version.mcfunction @@ -1 +1 @@ -tellraw @s {"rawtext":[{"text":"Commander API >> Version 1.3.1 (Beta Official Release)"}]} +tellraw @s {"rawtext":[{"text":"Commander API >> Version 1.4.0 (Beta Official Release)"}]} \ No newline at end of file diff --git a/manifest.json b/manifest.json index 8d9be6b..54920d6 100644 --- a/manifest.json +++ b/manifest.json @@ -4,7 +4,7 @@ "name": "Commander API", "description": "マインクラフト統合版のコマンドを拡張します。", "uuid": "ebac7142-c210-4d32-87ba-5650be52f456", - "version": [ 1, 3, 1 ], + "version": [ 1, 4, 0 ], "min_engine_version": [ 1, 19, 0 ] }, "metadata": { @@ -15,13 +15,13 @@ { "type": "data", "uuid": "36f425e9-10c9-466d-a620-0362a30c9b6f", - "version": [ 1, 3, 1 ] + "version": [ 1, 4, 0 ] }, { "language": "javascript", "type": "script", "uuid": "0d1f29e1-417f-48fb-b5fe-5a980830885a", - "version": [ 1, 3, 1 ], + "version": [ 1, 4, 0 ], "entry": "scripts/index.js" } ], diff --git a/scripts/index.js b/scripts/index.js index 4395eef..5ebdd84 100644 --- a/scripts/index.js +++ b/scripts/index.js @@ -19,15 +19,16 @@ import getScore from "./lib/getScore.js"; import { Database, ExtendedDatabase } from "./lib/Database.js"; import { easySafeParse, parsePos, safeParse, setVariable } from "./util.js"; import Config from "./config.js"; -import { Menu } from "./ui.js"; import ESON from "./lib/ESON.js"; +import { UI } from "./ui.js"; const world = Minecraft.world; const system = Minecraft.system; tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { // world.sendMessage("a") - for(const player of world.getPlayers()) { + // world.getPlayers().forEach(p => p.sendMessage(String(tps))) + world.getPlayers().forEach(async (player) => { player.getTags().forEach((t) => { if (t.startsWith("rename:")) { player.rename = t.replace("rename:", ""); @@ -59,6 +60,10 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { player.kick = t.replace("kick:","").replace(/'/g, "\""); player.removeTag(t); } + if (t.startsWith("knockback:")) { + player.knockback = t.replace("knockback:","").replace(/'/g, "\""); + player.removeTag(t); + } if (t === "kill") { player.kill(); player.removeTag(t); @@ -70,6 +75,10 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { if (player.isOp()) player.addTag("Capi:hasOp"); else player.removeTag("Capi:hasOp"); + // sneaking + if (player.isSneaking) player.addTag("Capi:sneaking"); + else player.removeTag("Capi:sneaking"); + player.setScore = (object, score = 0, type = "set") => { if (type === "set") { try { world.scoreboard.setScore(object, player.scoreboard, score); } catch { @@ -82,16 +91,7 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { } } - // speed - player.setScore("Capi:speedX", Math.round(player.getVelocity().x * 10)); - player.setScore("Capi:speedY", Math.round(player.getVelocity().y * 10)); - player.setScore("Capi:speedZ", Math.round(player.getVelocity().z * 10)); - player.setScore("Capi:speedXZ", Math.round(Math.sqrt((player.getVelocity().x ** 2) + (player.getVelocity().z ** 2)) * 10)); - player.setScore("Capi:speedXYZ", Math.round(Math.sqrt((player.getVelocity().x ** 2) + (player.getVelocity().y ** 2) + (player.getVelocity().z ** 2)) * 10)); - - // sneaking - if (player.isSneaking) player.addTag("Capi:sneaking"); - else player.removeTag("Capi:sneaking"); + // tshoot if (player.hasTag("Capi:system_tshoot")) { @@ -153,7 +153,7 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { if (Data.can_place_on) item.setCanPlaceOn(Data.can_place_on); if (Data.can_destroy) item.setCanDestroy(Data.can_destroy); if (Data.lock) item.lockMode = Minecraft.ItemLockMode[Data.lock]; - if (Data.keep_on_death) item.keepOnDeath = Boolean(Data.keep_on_death); + if (Data.keep_on_death) item.keepOnDeath = Data.keep_on_death === "true" ? true : false; if (typeof slot == "number") container.setItem(slot, item); else container.addItem(item); } catch (e) { @@ -191,6 +191,8 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { } + + // Run command if (player.run) { player.run.forEach(async commands => { @@ -226,6 +228,26 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { player.kick = false; } + // Knockback + if (player.knockback) { try { + const Data = await safeParse(player.knockback).catch((error) => { + console.error(error, error.stack); + player.sendMessage(`§c${error}`); + for (const ply of world.getPlayers({tags: ["Capi:hasOp"]})) ply.sendMessage(`§c${error}`); + }); + + const directionX = String(await setVariable(player, Data.directionX || Data[0] || 0)); + const directionZ = String(await setVariable(player, Data.directionZ || Data[1] || 0)); + const horizontalStrength = String(await setVariable(player, Data.horizontalStrength || Data[2] || 0)); + const verticalStrength = String(await setVariable(player, Data.verticalStrength || Data[3] || 0)); + player.applyKnockback( + Number(directionX.search(/[^0-9-.]/) >= 0 ? 0 : directionX), + Number(directionZ.search(/[^0-9-.]/) >= 0 ? 0 : directionZ), + Number(horizontalStrength.search(/[^0-9-.]/) >= 0 ? 0 : horizontalStrength), + Number(verticalStrength.search(/[^0-9-.]/) >= 0 ? 0 : verticalStrength)); + player.knockback = false; + } catch (e) {console.error(e)}} + // Join if (player.join) { player.setScore("Capi:playerJoinX", Math.floor(player.location.x)); @@ -237,6 +259,18 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { } // Set scoreboard + // speed + player.setScore("Capi:speedX", Math.round(player.getVelocity().x * 10)); + player.setScore("Capi:speedY", Math.round(player.getVelocity().y * 10)); + player.setScore("Capi:speedZ", Math.round(player.getVelocity().z * 10)); + player.setScore("Capi:speedXZ", Math.round(Math.sqrt((player.getVelocity().x ** 2) + (player.getVelocity().z ** 2)) * 10)); + player.setScore("Capi:speedXYZ", Math.round(Math.sqrt((player.getVelocity().x ** 2) + (player.getVelocity().y ** 2) + (player.getVelocity().z ** 2)) * 10)); + + // vector + player.setScore("Capi:vectorX", Math.round(player.getViewDirection().x * 100)); + player.setScore("Capi:vectorY", Math.round(player.getViewDirection().y * 100)); + player.setScore("Capi:vectorZ", Math.round(player.getViewDirection().z * 100)); + // health const health = Math.round(player.getComponent("health").current); player.setScore("Capi:health", health); @@ -273,8 +307,11 @@ tickEvent.subscribe("main", async ({currentTick, deltaTime, tps}) => { try { player.pushedTime = 0; } - if (player.hasTag("Capi:open_config_gui")) Menu(player); - } + if (player.hasTag("Capi:open_config_gui")) { + const ui = new UI(player); + ui.Menu(); + } + }) } catch (e) { console.error(e, e.stack) }}); @@ -344,6 +381,13 @@ world.events.beforeChat.subscribe(async chat => { player.addTag(`chat:${msg.replace(/"/g, "")}`); player.setScore("Capi:chatLength", msg.length); player.setScore("Capi:chatCount", 1, "add"); + if (Config.get("CancelSendMsgEnabled")) { + const CancelSendMsg = Config.get("CancelSendMsg"); + const start = CancelSendMsg?.start.some(v => v.length && msg.startsWith(v)); + const end = CancelSendMsg?.end.some(v => v.length && msg.endsWith(v)); + const include = CancelSendMsg?.include.some(v => v.length && msg.includes(v)); + if (start || end || include) return chat.cancel = true; + } if (mute || player.hasTag("mute")) { player.sendMessage(mute.length ? mute : "§cYou have been muted."); return chat.cancel = true; @@ -400,46 +444,6 @@ world.events.blockPlace.subscribe(async blockPlace => { player.setScore("Capi:blockPlaceZ", block.location.z); }); -// world.events.entityCreate.subscribe(entityCreate => { -// const entity = entityCreate.entity; - -// const { x, y, z } = entity.location; - -// player.setScore("Capi:EcreateX", Math.floor(x)); -// player.setScore("Capi:EcreateY", Math.floor(y)); -// player.setScore("Capi:EcreateZ", Math.floor(z)); - -// const details = { -// id: entity.id, -// name: entity.nameTag || entity.id -// } - -// entity.addTag(`Ecreate:${entity.id}`); -// entity.addTag(`EcreateD:${JSON.stringify(details)}`); -// }); - -// world.events.effectAdd.subscribe(effectAdd => { -// const player = effectAdd.entity; -// const amplifier = effectAdd.effect.amplifier; -// const duration = effectAdd.effect.duration; -// const displayName = effectAdd.effect.displayName.split(" ")[0]; -// if (player.typeId !== "minecraft:player") return; - -// player.setScore("Capi:effAddTick", duration); -// player.setScore("Capi:effAddLevel", amplifier); -// player.setScore("Capi:effAddState", effectAdd.effectState); - -// const details = { -// effect: displayName, -// level: amplifier, -// tick: duration, -// state: effectAdd.effectState -// } - -// player.addTag(`effectAdd:${displayName}`); -// player.addTag(`effectAddD:${JSON.stringify(details)}`); -// }); - world.events.playerSpawn.subscribe(async playerSpawn => { const { player, initialSpawn } = playerSpawn; if (initialSpawn) player.join = true; @@ -496,60 +500,111 @@ system.events.scriptEventReceive.subscribe(async scriptEventReceive => { const type = id.split(":")[1]; const player = sourceBlock || sourceEntity; - if (type.toLowerCase() === "explosion") { - const msg = message.split(" "), radius = Number(await setVariable(player, msg[0])) || 3, x = parsePos(await setVariable(player, msg[1]), player, "x"), y = parsePos(await setVariable(player, msg[2]), player, "y"), z = parsePos(await setVariable(player, msg[3]), player, "z"); - const loc = {x: x, y: y, z: z}; + if (type.toLowerCase() === "explosion") { try { + + const object = await easySafeParse(message); + if (!object.radius) return; + const radius = Number(object.radius); const options = { - allowUnderwater: msg[4] === "true" ? true : false, - breaksBlocks: msg[5] === "true" ? true : false, - causesFire: msg[6] === "true" ? true : false + allowUnderwater: object.options?.allow_under_water === "true" ? true : false, + breaksBlocks: object.options?.breaks_blocks === "true" ? true : false, + causesFire: object.options?.causes_fire === "true" ? true : false } + const x = parsePos(object.x, player, "x"); + const y = parsePos(object.y, player, "y"); + const z = parsePos(object.z, player, "z"); + const loc = {x: x, y: y, z: z}; player.dimension.createExplosion(loc, radius, options); - } else if (type.toLowerCase() === "spawnentity") { - const msg = message.split(" "), id = msg[0], x = parsePos(msg[1], player, "x"), y = parsePos(msg[2], player, "y"), z = parsePos(msg[3], player, "z"), name = msg[4]; - const loc = {x: x, y: y, z: z}, fire = Number(msg[5]); - if (!id) { - console.error(TypeError("Invalid entity ID.")); - player?.sendMessage(`§c${TypeError("Invalid entity ID.")}`); - for (const ply of world.getPlayers({tags: ["Capi:hasOp"]})) ply.sendMessage(`§c${TypeError("Invalid entity ID.")}`); - } + + } catch(e) {console.error(e)}} else if (["spawn", "entity"].every(v => type.toLowerCase().includes(v))) { + + const object = await easySafeParse(message); + if (!object.id) return; + const id = object.id; + + const name = object.name; + const fire = Number(object.set_on_fire); + + const x = parsePos(object.x, player, "x"); + const y = parsePos(object.y, player, "y"); + const z = parsePos(object.z, player, "z"); + const loc = {x: x, y: y, z: z}; const entity = player.dimension.spawnEntity(id, loc); if (name) entity.nameTag = name; if (fire) entity.setOnFire(fire); - } else if (type.toLowerCase() === "spawnitem") { - const msg = message.split(" "), id = msg[0], amount = Number(msg[1]) || 1, x = parsePos(msg[2], player, "x"), y = parsePos(msg[3], player, "y"), z = parsePos(msg[4], player, "z"), name = msg[5]; - const loc = {x: x, y: y, z: z}; - if (!id) { - console.error(TypeError("Invalid item ID.")); - player?.sendMessage(`§c${TypeError("Invalid item ID.")}`); - for (const ply of world.getPlayers({tags: ["Capi:hasOp"]})) ply.sendMessage(`§c${TypeError("Invalid item ID.")}`); - } - - const item = new Minecraft.ItemStack(Minecraft.ItemTypes.get(id), amount); - if (name) item.nameTag = name; + + } else if (["spawn", "item"].every(v => type.toLowerCase().includes(v))) { + const object = await easySafeParse(message); + if (!object.item) return; + const amount = object.amount ? Number(object.amount) : 1; + const itemName = object.item.replace("minecraft:", ""); + const item = new Minecraft.ItemStack(Minecraft.ItemTypes.get(itemName), amount); + if (object.name) item.nameTag = await setVariable(player, object.name); + if (object.lore) { + for (let v in object.lore) object.lore[v] = await setVariable(player, object.lore[v]); + item.setLore(object.lore); + } + if (object.enchants) { + /** @type { Minecraft.EnchantmentList } */ + const enchantments = item.getComponent("enchantments").enchantments; + for (let i = 0; i < object.enchants.length; i++) { + if (!object.enchants[i].name) return; + let enchantsName = object.enchants[i].name; + let enchantsLevel = 1; + if (object.enchants[i].level) enchantsLevel = Number(object.enchants[i].level); + enchantments.addEnchantment(new Minecraft.Enchantment(Minecraft.MinecraftEnchantmentTypes[enchantsName], enchantsLevel)); + } + item.getComponent("enchantments").enchantments = enchantments; + } + if (object.can_place_on) item.setCanPlaceOn(object.can_place_on); + if (object.can_destroy) item.setCanDestroy(object.can_destroy); + if (object.lock) item.lockMode = Minecraft.ItemLockMode[object.lock]; + if (object.keep_on_death) item.keepOnDeath = object.keep_on_death === "true" ? true : false; + const x = parsePos(object.x, player, "x"); + const y = parsePos(object.y, player, "y"); + const z = parsePos(object.z, player, "z"); + const loc = {x: x, y: y, z: z}; player.dimension.spawnItem(item, loc); - } else if (type.toLowerCase() === "spawnparticle") { - const msg = message.split(" "), id = msg[0], x = parsePos(msg[1], player, "x"), y = parsePos(msg[2], player, "y"), z = parsePos(msg[3], player, "z"), r = Number(msg[4]) || 1, g = Number(msg[5]) || 1, b = Number(msg[6]) || 1, variable = msg[7]; + } else if (["spawn", "particle"].every(v => type.toLowerCase().includes(v))) { + + const object = await easySafeParse(message); + if (!object.id) return; + const id = object.id; + + const x = parsePos(object.x, player, "x"); + const y = parsePos(object.y, player, "y"); + const z = parsePos(object.z, player, "z"); const loc = {x: x, y: y, z: z}; - if (!id) { - console.error(TypeError("Invalid particle ID.")); - player?.sendMessage(`§c${TypeError("Invalid particle ID.")}`); - for (const ply of world.getPlayers({tags: ["Capi:hasOp"]})) ply.sendMessage(`§c${TypeError("Invalid particle ID.")}`); - } + + const r = Number(object?.color.r); + const g = Number(object?.color.g); + const b = Number(object?.color.b); + const variable = Number(object.variable); player.dimension.spawnParticle(id, loc, new Minecraft.MolangVariableMap().setColorRGB(`variable.${variable}`, new Minecraft.Color(r, g, b, 1))); } else if (type.toLowerCase() === "say") { + if (player instanceof Minecraft.Player) world.sendMessage(await setVariable(player, message)); else world.sendMessage(await setVariable({}, message)); + } else if (["teleport","tp"].includes(type.toLowerCase()) && player instanceof Minecraft.Player) { - const msg = message.split(" "), x = parsePos(msg[0], player, "x"), y = parsePos(msg[1], player, "y"), z = parsePos(msg[2], player, "z") - const rx = parsePos(msg[3], player, "rx"), ry = parsePos(msg[4], player, "ry"), toDimension = msg[5] || player.dimension.id; - player.teleport({x, y, z}, world.getDimension(toDimension), rx, ry); + const object = await easySafeParse(message); + + const x = parsePos(object.x, player, "x"); + const y = parsePos(object.y, player, "y"); + const z = parsePos(object.z, player, "z"); + const rx = parsePos(object.rx, player, "rx"); + const ry = parsePos(object.ry, player, "ry"); + const loc = {x: x, y: y, z: z}; + + const dimension = object.dimension || player.dimension.id; + + player.teleport(loc, world.getDimension(dimension), rx, ry); + } - -}, { namespaces: ["Capi"] }); \ No newline at end of file +}, { namespaces: ["Capi"] }); diff --git a/scripts/ui.js b/scripts/ui.js index 10f365f..c6d97b4 100644 --- a/scripts/ui.js +++ b/scripts/ui.js @@ -20,88 +20,133 @@ import { Database, ExtendedDatabase } from "./lib/Database"; import { setVariable } from "./util"; import Config from "./config"; +export class UI { + /** + * + * @param {Minecraft.Player} player + */ + constructor(player) { + this.player = player; + } -export function Menu(player) { - player.removeTag("Capi:open_config_gui"); - const Menu = new MinecraftUI.ActionFormData() - .title("§lCommander API") - .body("設定の変更後は §7/reload§r を実行して設定を反映させてください。") - .button("§lプレイヤー退出メッセージ") - .button("§lチャットUI") - .button("§l§c閉じる") - .show(player).then(response => { - if (response.selection === 0) LeaveMsg(player); - if (response.selection === 1) ChatUI(player); - }); -} + Menu() { try { + this.player.removeTag("Capi:open_config_gui"); + const Form = new MinecraftUI.ActionFormData() + .title("§lCommander API") + .body("設定の変更後は §7/reload§r を実行して設定を反映させてください。") + .button("§lプレイヤー退出メッセージ") + .button("§lチャットUI") + .button("§l送信キャンセル") + .button("§l§4リセット") + .button("§l§c閉じる") + .show(this.player).then(response => { + if (response.selection === 0) this.LeaveMsg(); + if (response.selection === 1) this.ChatUI(); + if (response.selection === 2) this.CancelSendMsg(); + if (response.selection === 3) Config.clear(); + }); + } catch (e) {console.error(e)}} -const MenuBack = (player) => Menu(player); - -function LeaveMsg(player) { - const Menu = new MinecraftUI.ActionFormData() - .title("§lCommander API") - .body(`ステータス: ${Config.get("LeaveMsgEnabled") ? "有効" : "無効"}\nメッセージ: "${Config.get("LeaveMsg")}"`) - .button("§l設定する"); - if (Config.get("LeaveMsgEnabled")) Menu.button("§l§c無効にする"); - else Menu.button("§l§2有効にする"); - - Menu.button("§l戻る") - .button("§l§c閉じる") - .show(player).then(response => { - if (response.selection === 0) LeaveMsgConfig(player); - if (response.selection === 1) { - if (Config.get("LeaveMsgEnabled")) Config.set("LeaveMsgEnabled", false); - else Config.set("LeaveMsgEnabled", true); - LeaveMsgBack(player); - } - if (response.selection === 2) MenuBack(player); - }); -} - -function LeaveMsgConfig(player) { - const Menu = new MinecraftUI.ModalFormData() - .title("§lCommander API") - .textField("メッセージ", "(例) {name} がサーバーから抜けた!", Config.get("LeaveMsg") || null) - .show(player).then(response => { - if (response.formValues[0].length) Config.set("LeaveMsg", String(response.formValues[0])); - else if (!response.canceled) Config.set("LeaveMsg", null); - LeaveMsgBack(player); - }); -} + LeaveMsg() { try { + const Form = new MinecraftUI.ActionFormData() + .title("§lCommander API") + .body(`ステータス: ${Config.get("LeaveMsgEnabled") ? "有効" : "無効"}\nメッセージ: "${Config.get("LeaveMsg")}"`) + .button("§l設定する"); + if (Config.get("LeaveMsgEnabled")) Form.button("§l§c無効にする"); + else Form.button("§l§2有効にする"); + + Form.button("§l戻る") + .button("§l§c閉じる") + .show(this.player).then(response => { + if (response.selection === 0) this.LeaveMsgConfig(); + if (response.selection === 1) { + if (Config.get("LeaveMsgEnabled")) Config.set("LeaveMsgEnabled", false); + else Config.set("LeaveMsgEnabled", true); + this.LeaveMsg(); + } + if (response.selection === 2) this.Menu(); + }); + } catch (e) {console.error(e)}} -const LeaveMsgBack = (player) => LeaveMsg(player); + LeaveMsgConfig() { + const Form = new MinecraftUI.ModalFormData() + .title("§lCommander API") + .textField("メッセージ", "(例) {name} がサーバーから抜けた!", Config.get("LeaveMsg") || null) + .show(this.player).then(response => { + if (response.formValues[0].length) Config.set("LeaveMsg", String(response.formValues[0])); + else if (!response.canceled) Config.set("LeaveMsg", null); + this.LeaveMsg(); + }); + } -function ChatUI(player) { - const Menu = new MinecraftUI.ActionFormData() - .title("§lCommander API") - .body(`ステータス: ${Config.get("ChatUIEnabled") ? "有効" : "無効"}\nUI: "${Config.get("ChatUI")}"`) - .button("§l設定する"); - if (Config.get("ChatUIEnabled")) Menu.button("§l§c無効にする"); - else Menu.button("§l§2有効にする"); + ChatUI() { + const Form = new MinecraftUI.ActionFormData() + .title("§lCommander API") + .body(`ステータス: ${Config.get("ChatUIEnabled") ? "有効" : "無効"}\nUI: "${Config.get("ChatUI")}"`) + .button("§l設定する"); + if (Config.get("ChatUIEnabled")) Form.button("§l§c無効にする"); + else Form.button("§l§2有効にする"); + + Form.button("§l戻る") + .button("§l§c閉じる") + .show(this.player).then(response => { + if (response.selection === 0) this.ChatUIConfig(); + if (response.selection === 1) { + if (Config.get("ChatUIEnabled")) Config.set("ChatUIEnabled", false); + else Config.set("ChatUIEnabled", true); + this.ChatUI(); + } + if (response.selection === 2) this.Menu(); + }); + } - Menu.button("§l戻る") - .button("§l§c閉じる") - .show(player).then(response => { - if (response.selection === 0) ChatUIConfig(player); - if (response.selection === 1) { - if (Config.get("ChatUIEnabled")) Config.set("ChatUIEnabled", false); - else Config.set("ChatUIEnabled", true); - ChatUIBack(player); - } - if (response.selection === 2) MenuBack(player); - }); -} + ChatUIConfig() { + + const Form = new MinecraftUI.ModalFormData() + .title("§lCommander API") + .textField("UI", "(例) {name} >> {message}", Config.get("ChatUI") || null) + .show(this.player).then(response => { + if (response.formValues[0].length) Config.set("ChatUI", String(response.formValues[0])); + else if (!response.canceled) Config.set("ChatUI", null); + this.ChatUI(); + }); + } -function ChatUIConfig(player) { + CancelSendMsg () { + const Form = new MinecraftUI.ActionFormData() + .title("§lCommander API") + .body(`ステータス: ${Config.get("CancelSendMsgEnabled") ? "有効" : "無効"}\nで始まっているか: "§a${Config.get("CancelSendMsg")?.start.join("§r, §a")}§r"\nで終わっているか: "§a${Config.get("CancelSendMsg")?.end.join("§r, §a")}§r"\nが含まれているか: "§a${Config.get("CancelSendMsg")?.include.join("§r, §a")}§r"`) + .button("§l設定する"); + if (Config.get("CancelSendMsgEnabled")) Form.button("§l§c無効にする"); + else Form.button("§l§2有効にする"); - const Menu = new MinecraftUI.ModalFormData() - .title("§lCommander API") - .textField("UI", "(例) {name} >> {message}", Config.get("ChatUI") || null) - .show(player).then(response => { - if (response.formValues[0].length) Config.set("ChatUI", String(response.formValues[0])); - else if (!response.canceled) Config.set("ChatUI", null); - ChatUIBack(player); - }); -} + Form.button("§l戻る") + .button("§l§c閉じる") + .show(this.player).then(response => { + if (response.selection === 0) this.CancelSendMsgConfig(); + if (response.selection === 1) { + if (Config.get("CancelSendMsgEnabled")) Config.set("CancelSendMsgEnabled", false); + else Config.set("CancelSendMsgEnabled", true); + this.CancelSendMsg(); + } + if (response.selection === 2) this.Menu(); + }); + } -const ChatUIBack = (player) => ChatUI(player); \ No newline at end of file + CancelSendMsgConfig () { + const Form = new MinecraftUI.ModalFormData() + .title("§lCommander API") + .textField("で始まっているか", "(例) !, ?, #", Config.get("CancelSendMsg")?.start.join(", ") || null) + .textField("で終わっているか", "(例) ,, ., :)", Config.get("CancelSendMsg")?.end.join(", ") || null) + .textField("が含まれているか", "(例) help, !Form", Config.get("CancelSendMsg")?.include.join(", ") || null) + .show(this.player).then(response => { + const object = { + start: response.formValues[0].split(", "), + end: response.formValues[1].split(", "), + include: response.formValues[2].split(", ") + } + Config.set("CancelSendMsg", object); + this.CancelSendMsg(); + }); + } +} \ No newline at end of file diff --git a/scripts/util.js b/scripts/util.js index cc849c5..d431bb1 100644 --- a/scripts/util.js +++ b/scripts/util.js @@ -24,11 +24,15 @@ import getScore from "./lib/getScore.js"; * @param {string} text * @returns */ -export function setVariable(player, text) { - return new Promise(async (resolve, reject) => { try { +export async function setVariable(player, text) { + return await new Promise(async (resolve, reject) => { try { + + if (!player instanceof Minecraft.Player) reject("player needs Player Class"); if (!text?.length) resolve(text); const dataLength = text.split("").filter(t => t === "{").length; + if (!dataLength) resolve(text); + for (let i = 0; i < dataLength; i++) { text = text.replace(/({name}|{name,})/i, player.name); text = text.replace(/({nametag}|{nametag,})/i, player.nameTag); @@ -72,8 +76,9 @@ export function setVariable(player, text) { if (![-1, 0, 1].includes(dimension)) dimension = text.replace(new RegExp(`({dimension:${dimension}}|{dimension:${dimension},})`, "i"), "null"); } } catch {} + + if (dataLength - i === 1) resolve(text); } - resolve(text); } catch (e) {reject(e)}}) }