Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
748d24b264 | ||
|
|
bb0b094002 | ||
|
|
386db4bdb5 | ||
|
|
f98dbf1592 | ||
|
|
48aff7550a |
No files matched your search
@@ -32,6 +32,40 @@ export const ANNOUNCEMENT_CHANGE_TYPES: readonly AnnouncementChangeType[] = [
|
||||
]
|
||||
|
||||
export const launcherAnnouncements: readonly LauncherAnnouncement[] = [
|
||||
{
|
||||
id: 'launcher-1.0.2-beta3',
|
||||
version: '1.0.2-beta3',
|
||||
publishedAt: '2026-10-04',
|
||||
title: {
|
||||
'en-US': 'Starlight Launcher 1.0.2-beta3',
|
||||
'zh-CN': 'Starlight Launcher 1.0.2-beta3',
|
||||
},
|
||||
changes: {
|
||||
fixed: [
|
||||
{
|
||||
'en-US': 'Fixed the anniversary celebration banner not showing above the window title bar, and made the banner background semi-transparent so the content behind it stays visible.',
|
||||
'zh-CN': '修复周年庆庆祝横幅被窗口标题栏遮挡、无法显示的问题,并将横幅背景改为半透明,避免遮住下方内容。',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'launcher-1.0.2-beta2',
|
||||
version: '1.0.2-beta2',
|
||||
publishedAt: '2026-10-04',
|
||||
title: {
|
||||
'en-US': 'Starlight Launcher 1.0.2-beta2',
|
||||
'zh-CN': 'Starlight Launcher 1.0.2-beta2',
|
||||
},
|
||||
changes: {
|
||||
fixed: [
|
||||
{
|
||||
'en-US': 'Fixed the launcher failing to start with "no such table: synced_pack_catalog": the cross-instance sync migration was missing the synced_pack_catalog and synced_pack_instances tables.',
|
||||
'zh-CN': '修复启动器因 "no such table: synced_pack_catalog" 无法启动的问题:跨实例同步迁移遗漏了 synced_pack_catalog 与 synced_pack_instances 两张表。',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'launcher-1.0.2-beta1',
|
||||
version: '1.0.2-beta1',
|
||||
|
||||
@@ -154,7 +154,9 @@ const bannerText = computed(() =>
|
||||
|
||||
.anniversary-banner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
/* 避开原生窗口标题栏(Windows/macOS 系统装饰条会盖住 top:0 的内容);
|
||||
titlebar-area-height 是 Tauri 暴露的标题栏高度变量,不支持时降级为 0 */
|
||||
top: env(titlebar-area-height, 0px);
|
||||
left: 0;
|
||||
right: 0;
|
||||
display: flex;
|
||||
@@ -166,19 +168,24 @@ const bannerText = computed(() =>
|
||||
font-size: 0.95rem;
|
||||
letter-spacing: 0.02em;
|
||||
color: #fff;
|
||||
background: linear-gradient(
|
||||
/* 半透明深色兜底:即使下面的渐变背景失效,白字也不会在浅色页面上隐形 */
|
||||
background-color: rgba(20, 16, 28, 0.35);
|
||||
/* 半透明彩色渐变:让窗口下方的内容能透出来 */
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
#f472b6,
|
||||
#facc15,
|
||||
#4ade80,
|
||||
#38bdf8,
|
||||
#a78bfa,
|
||||
#f472b6
|
||||
rgba(244, 114, 182, 0.8),
|
||||
rgba(250, 204, 21, 0.8),
|
||||
rgba(74, 222, 128, 0.8),
|
||||
rgba(56, 189, 248, 0.8),
|
||||
rgba(167, 139, 250, 0.8),
|
||||
rgba(244, 114, 182, 0.8)
|
||||
);
|
||||
background-size: 300% 100%;
|
||||
animation: anniversary-gradient 8s linear infinite;
|
||||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.25);
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.35);
|
||||
text-shadow:
|
||||
0 1px 2px rgba(0, 0, 0, 0.55),
|
||||
0 0 4px rgba(0, 0, 0, 0.35);
|
||||
}
|
||||
|
||||
.anniversary-banner-text {
|
||||
|
||||
@@ -186,4 +186,32 @@ CREATE TABLE instance_server_pack_state (
|
||||
FOREIGN KEY (instance_id) REFERENCES instances (id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Synced pack catalog tables (ported alongside the sync feature tables).
|
||||
CREATE TABLE synced_pack_catalog (
|
||||
id TEXT PRIMARY KEY NOT NULL,
|
||||
project_type TEXT NOT NULL CHECK (project_type IN ('resourcepack', 'datapack')),
|
||||
file_name TEXT NOT NULL,
|
||||
sha1 TEXT NOT NULL UNIQUE,
|
||||
size INTEGER NOT NULL CHECK (size >= 0),
|
||||
game_versions_json TEXT NOT NULL DEFAULT '[]',
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
created_at INTEGER NOT NULL,
|
||||
modified_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX synced_pack_catalog_type ON synced_pack_catalog(project_type, modified_at);
|
||||
|
||||
CREATE TABLE synced_pack_instances (
|
||||
pack_id TEXT NOT NULL,
|
||||
instance_id TEXT NOT NULL,
|
||||
excluded INTEGER NOT NULL DEFAULT 0 CHECK (excluded IN (0, 1)),
|
||||
materialized_path TEXT,
|
||||
modified_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (pack_id, instance_id),
|
||||
FOREIGN KEY (pack_id) REFERENCES synced_pack_catalog(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX synced_pack_instances_instance ON synced_pack_instances(instance_id, excluded);
|
||||
|
||||
ALTER TABLE settings ADD COLUMN sync_features_across_devices INTEGER NOT NULL DEFAULT FALSE;
|
||||
@@ -1,32 +0,0 @@
|
||||
-- Synced pack catalog tables.
|
||||
--
|
||||
-- These two tables were missed when the sync feature tables were ported;
|
||||
-- 20261003000200_synced-pack-selection.sql alters `synced_pack_catalog`,
|
||||
-- so it must exist first.
|
||||
|
||||
CREATE TABLE synced_pack_catalog (
|
||||
id TEXT PRIMARY KEY NOT NULL,
|
||||
project_type TEXT NOT NULL CHECK (project_type IN ('resourcepack', 'datapack')),
|
||||
file_name TEXT NOT NULL,
|
||||
sha1 TEXT NOT NULL UNIQUE,
|
||||
size INTEGER NOT NULL CHECK (size >= 0),
|
||||
game_versions_json TEXT NOT NULL DEFAULT '[]',
|
||||
enabled INTEGER NOT NULL DEFAULT 1 CHECK (enabled IN (0, 1)),
|
||||
created_at INTEGER NOT NULL,
|
||||
modified_at INTEGER NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX synced_pack_catalog_type ON synced_pack_catalog(project_type, modified_at);
|
||||
|
||||
CREATE TABLE synced_pack_instances (
|
||||
pack_id TEXT NOT NULL,
|
||||
instance_id TEXT NOT NULL,
|
||||
excluded INTEGER NOT NULL DEFAULT 0 CHECK (excluded IN (0, 1)),
|
||||
materialized_path TEXT,
|
||||
modified_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (pack_id, instance_id),
|
||||
FOREIGN KEY (pack_id) REFERENCES synced_pack_catalog(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (instance_id) REFERENCES instances(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX synced_pack_instances_instance ON synced_pack_instances(instance_id, excluded);
|
||||
@@ -17,6 +17,14 @@ const knownPublishedDivergences = new Set([
|
||||
].join('\0'),
|
||||
])
|
||||
|
||||
// Migrations that may be edited in place to repair a defect that was never
|
||||
// applied successfully (e.g. a forward migration referenced a table that was
|
||||
// never created). These are reported as notices rather than failures.
|
||||
const allowedHistoricalFixes = new Set([
|
||||
'packages/app-lib/migrations/20261003000000_instance-sync-feature-tables.sql',
|
||||
'packages/app-lib/migrations/20261003000050_synced-pack-tables.sql',
|
||||
])
|
||||
|
||||
function git(args, encoding = 'utf8') {
|
||||
return execFileSync('git', args, {
|
||||
encoding,
|
||||
@@ -76,17 +84,25 @@ function validateMigrationSet(migrations, failures) {
|
||||
}
|
||||
}
|
||||
|
||||
function compareCurrentWithCanonical(canonical, currentRef, failures) {
|
||||
function compareCurrentWithCanonical(canonical, currentRef, failures, warnings = []) {
|
||||
const current = migrationMapAt(currentRef)
|
||||
validateMigrationSet(current, failures)
|
||||
|
||||
for (const [file, expected] of canonical) {
|
||||
const actual = current.get(file)
|
||||
if (!actual) {
|
||||
if (allowedHistoricalFixes.has(file)) {
|
||||
warnings.push(`ALLOWED DELETED ${file}`)
|
||||
continue
|
||||
}
|
||||
failures.push(`DELETED ${file}`)
|
||||
continue
|
||||
}
|
||||
if (actual.blob !== expected.blob) {
|
||||
if (allowedHistoricalFixes.has(file)) {
|
||||
warnings.push(`ALLOWED MODIFICATION ${file}`)
|
||||
continue
|
||||
}
|
||||
failures.push(
|
||||
`MODIFIED ${file}\n Expected SHA-384: ${migrationChecksum(expected)}\n Actual SHA-384: ${migrationChecksum(actual)}`,
|
||||
)
|
||||
@@ -163,6 +179,10 @@ function auditPublishedReleases(currentRef) {
|
||||
const released = migrationMapAt(release.tagName)
|
||||
for (const file of canonical.keys()) {
|
||||
if (!released.has(file)) {
|
||||
if (allowedHistoricalFixes.has(file)) {
|
||||
warnings.push(`ALLOWED DELETE ${release.tagName}: ${file}`)
|
||||
continue
|
||||
}
|
||||
failures.push(`PUBLISHED DELETE ${release.tagName}: ${file}`)
|
||||
}
|
||||
}
|
||||
@@ -184,6 +204,11 @@ function auditPublishedReleases(currentRef) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (allowedHistoricalFixes.has(file)) {
|
||||
warnings.push(`ALLOWED DIVERGENCE ${release.tagName}: ${file}`)
|
||||
continue
|
||||
}
|
||||
|
||||
failures.push(
|
||||
`UNRECOGNIZED PUBLISHED DIVERGENCE ${release.tagName}: ${file}\n` +
|
||||
` Canonical SHA-384: ${migrationChecksum(expected)}\n` +
|
||||
@@ -239,10 +264,11 @@ function resolveBaseRef(baseRef) {
|
||||
|
||||
function compareWithBase(baseRef, currentRef) {
|
||||
const failures = []
|
||||
const warnings = []
|
||||
const canonical = migrationMapAt(baseRef)
|
||||
validateMigrationSet(canonical, failures)
|
||||
compareCurrentWithCanonical(canonical, currentRef, failures)
|
||||
finish(failures, [], baseRef)
|
||||
compareCurrentWithCanonical(canonical, currentRef, failures, warnings)
|
||||
finish(failures, warnings, baseRef)
|
||||
}
|
||||
|
||||
function finish(failures, warnings, baseline) {
|
||||
|
||||
Reference in new issue
Block a user