From 9e59abde53cb7634805719fc0fb120aec0f03aef Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Thu, 10 Sep 2026 19:00:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20AGC=20=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=BF=AB=E9=80=9F=E7=BC=96=E8=BE=91=E8=A2=AB=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=20400=20=E6=8B=92=E7=BB=9D=EF=BC=9A=E6=9D=A5=E6=BA=90=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E8=A1=A8=E6=94=B9=E4=B8=BA=E4=B8=8E=E5=85=B1=E4=BA=AB?= =?UTF-8?q?=E5=A5=91=E7=BA=A6=E5=AF=B9=E9=BD=90=E7=9A=84=E9=9D=99=E6=80=81?= =?UTF-8?q?=E5=9B=BE=E9=9B=86=E5=90=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `ensure_editor_image_edit_source_kind_allowed` 的白名单换成静态图类型表 `EDITOR_IMAGE_EDIT_STATIC_IMAGE_ASSET_KINDS`(canonical 静态图类型 + 合法 legacy 类型) - 保留 `mediaType == image` 的 AND 门,视频 / 音频 / 序列帧等非静态媒体照旧拒绝 - 覆盖实测被拒的 `art-spritesheet` / `ui`,以及 canonical 映射输入域 `art-spritesheet-slice` / `ui-prototype` / `game-art` / `game-background` / `character-art` / `illustration` --- .../crates/api-server/src/editor_project.rs | 50 ++++++++++++++----- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/server-rs/crates/api-server/src/editor_project.rs b/server-rs/crates/api-server/src/editor_project.rs index 192e70c0c..05486f056 100644 --- a/server-rs/crates/api-server/src/editor_project.rs +++ b/server-rs/crates/api-server/src/editor_project.rs @@ -4105,24 +4105,50 @@ fn align_editor_image_edit_dimension(value: u32) -> u32 { value.saturating_add(15) / 16 * 16 } +/// 图片快速编辑端点允许的**静态图**来源类型。 +/// +/// 口径依据 `packages/shared/src/contracts/gameCreationApp.ts` 的 +/// `canonicalGameCreationAppAssetKind()`(等价实现见 +/// `server-rs/crates/shared-contracts/src/game_creation_app.rs`):以「媒体类型为静态图的 +/// canonical 类型」为权威集合,并额外收下合法 legacy 类型本身(平台还有别的写入口按本地 +/// manifest 原始类型登记来源资源,客户端不会先做 canonical 归一)。 +/// `canonicalGameCreationAppAssetKind()` 对未知值回退 `image`,因此两个入口都放行的这些值 +/// 在共享契约里语义等价,静态图集合对 canonical 归一封闭,不会漏放合法静态图来源。 +/// +/// 必须与 `media_type == image` 一起构成 AND 门:视频、音频、序列帧等非静态媒体即使挂着 +/// 图片类 assetKind 也照旧拒绝。 +pub(crate) const EDITOR_IMAGE_EDIT_STATIC_IMAGE_ASSET_KINDS: [&str; 17] = [ + // canonical 静态图类型 + "image", + "scene", + "character", + "icon", + "icon-spritesheet", + "icon-spec", + "ui-design", + "publication-material", + "spec", + // 指向上述 canonical 类型的合法 legacy 类型 + "game-background", + "character-art", + "game-art", + "illustration", + "art-spritesheet", + "art-spritesheet-slice", + "ui-prototype", + // AGC 本地 manifest 等在用的等价静态图类型 + "ui", +]; + pub(crate) fn ensure_editor_image_edit_source_kind_allowed( asset_kind: Option<&str>, media_type: Option<&str>, ) -> Result<(), AppError> { let asset_kind = asset_kind.map(str::trim).filter(|value| !value.is_empty()); let media_type = media_type.map(str::trim).filter(|value| !value.is_empty()); - let asset_kind_allowed = matches!( - asset_kind, - None | Some( - "spec" - | "character" - | "icon-spritesheet" - | "icon-spec" - | "publication-material" - | "ui-design" - | "scene" - ) - ); + let asset_kind_allowed = asset_kind.is_none_or(|asset_kind| { + EDITOR_IMAGE_EDIT_STATIC_IMAGE_ASSET_KINDS.contains(&asset_kind) + }); let media_type_allowed = matches!(media_type, None | Some("image")); if asset_kind_allowed && media_type_allowed { return Ok(());