Skip to content

Commit

Permalink
检查编辑器更新
Browse files Browse the repository at this point in the history
  • Loading branch information
sumneko committed Dec 10, 2024
1 parent 34859b6 commit 9fd91ea
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 26 deletions.
1 change: 1 addition & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ class Helper {
globalScript.init();
luaLanguage.init();
ecaCompiler.init();
y3.version.init();
}, 100);
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/launchEditor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ export class EditorLauncher {
return false;
}

if (await y3.version.askUpdate()) {
return false;
}

await this.runPlugin();

let project_path = projectUri.fsPath.replaceAll("\\", "/") + '/header.project';
Expand Down
5 changes: 4 additions & 1 deletion src/launchGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ export class GameLauncher {
return false;
}


if (await y3.version.askUpdate()) {
return false;
}

await vscode.workspace.fs.createDirectory(vscode.Uri.joinPath(env.scriptUri!, '.log'));
let suc = await this.runPlugin();
if (!suc) {
Expand Down
11 changes: 4 additions & 7 deletions src/mainMenu/pages/environments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,21 +35,23 @@ export class 环境 extends TreeNode {
iconPath: new vscode.ThemeIcon('versions'),
description: '获取中...',
tooltip: '获取中...',
init: (node) => subscribeUpdate(node),
update: async (node) => {
let version = await y3.version.getClient();
node.description = version ? String(version.display) : '获取失败...';
node.tooltip = version ? version.display : undefined;
node.tooltip = version ? String(version.version) : undefined;
subscribeUpdate(node);
},
}),
new TreeNode('最新版本', {
iconPath: new vscode.ThemeIcon('cloud-download'),
description: '获取中...',
tooltip: '获取中...',
init: (node) => subscribeUpdate(node),
update: async (node) => {
let version = await y3.version.getServer();
node.description = version ? String(version.display) : '获取失败...';
node.tooltip = version ? String(version.version) : undefined;
subscribeUpdate(node);
},
}),
] : undefined;
Expand All @@ -73,12 +75,7 @@ export class 环境 extends TreeNode {
}
};

let hasSubscribed = false;
function subscribeUpdate(node: TreeNode) {
if (hasSubscribed) {
return;
}
hasSubscribed = true;
y3.version.onDidChange(() => {
node.refresh();
});
Expand Down
28 changes: 26 additions & 2 deletions src/mainMenu/pages/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,6 @@ export class 功能 extends TreeNode {
return env.scriptUri !== undefined;
},
collapsibleState: vscode.TreeItemCollapsibleState.Expanded,
update: async (node) => {
},
childs: [
new TreeNode('初始化Y3库', {
command: {
Expand All @@ -126,6 +124,32 @@ export class 功能 extends TreeNode {
&& !await globalScript.isEnabled();
}
}),
new TreeNode('编辑器需要更新!', {
iconPath: new vscode.ThemeIcon('symbol-event'),
init: (node) => {
y3.version.onDidChange(async () => {
node.parent?.refresh();
});
},
update: async (node) => {
let client = await y3.version.getClient();
let server = await y3.version.getServer();
node.description = `${client?.display} -> ${server?.display}`;
node.tooltip = `${client?.version} -> ${server?.version}`;
node.command = {
command: 'y3-helper.shell',
title: '启动编辑器',
arguments: [
'start',
y3.env.editorUri?.fsPath,
]
};
},
show: async () => {
return y3.env.editorUri !== undefined
&& await y3.version.needUpdate();
}
}),
new TreeNode('启动游戏', {
command: {
command: 'y3-helper.launchGame',
Expand Down
10 changes: 10 additions & 0 deletions src/mainMenu/treeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface TreeNodeOptional {
onDidChangeCheckboxState?: (state: vscode.TreeItemCheckboxState) => void;
childs?: TreeNode[];
update?: (node: TreeNode) => void | Thenable<void>;
init?: (node: TreeNode) => void | Thenable<void>;
show?: boolean | ((node: TreeNode) => boolean | Promise<boolean>);
data?: any;
}
Expand All @@ -19,6 +20,7 @@ export class TreeNode extends vscode.TreeItem {
childs?: TreeNode[];
parent?: TreeNode;
show?: TreeNodeOptional["show"] = true;
init?: TreeNodeOptional["init"];
update?: TreeNodeOptional["update"];
onDidChangeCheckboxState?: TreeNodeOptional["onDidChangeCheckboxState"];
data?: any;
Expand All @@ -31,6 +33,12 @@ export class TreeNode extends vscode.TreeItem {
this.description = optional.description;
this.contextValue = optional.contextValue;
this.childs = optional.childs;
if (optional.init) {
this.init = async (node) => {
this.init = undefined;
return await optional.init?.(node);
};
}
this.update = optional.update;
this.show = optional.show ?? true;
this.collapsibleState = optional.collapsibleState;
Expand Down Expand Up @@ -125,6 +133,7 @@ export class TreeProvider implements vscode.TreeDataProvider<TreeNode> {
let childs = [];
for (const child of node.childs) {
if (child.show instanceof Function) {
await child.init?.(child);
let show = await child.show(child);
if (!show) {
continue;
Expand All @@ -144,6 +153,7 @@ export class TreeProvider implements vscode.TreeDataProvider<TreeNode> {

async getTreeItem(node: TreeNode): Promise<TreeNode> {
node.tree = this;
await node.init?.(node);
await node.update?.(node);
node.updateChilds();
node.collapsibleState = node.collapsibleState ?? (node.childs ? vscode.TreeItemCollapsibleState.Collapsed : vscode.TreeItemCollapsibleState.None);
Expand Down
104 changes: 88 additions & 16 deletions src/tools/version.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
import * as y3 from 'y3-helper';
import * as vscode from 'vscode';
import { runShell } from '../runShell';

interface Version {
version: number;
display: string;
}

export async function getClient(): Promise<Version | undefined> {
const filePaths = [
"LocalData/Patch/editor_patchmd5_windows64_normal.txt",
"Package/editor_patchmd5_windows64_normal.txt"
];

let lastClient: Version | undefined;

async function _getClient(): Promise<Version | undefined> {
await y3.env.editorReady();
if (!y3.env.editorUri) {
return undefined;
}
for (const filePath of [
"LocalData/Patch/editor_patchmd5_windows64_normal.txt",
"Package/editor_patchmd5_windows64_normal.txt"
]) {
for (const filePath of filePaths) {
const fullUri = y3.uri(y3.env.editorUri, '..', filePath);
if (!await y3.fs.isExists(fullUri)) {
continue;
Expand All @@ -34,7 +39,11 @@ export async function getClient(): Promise<Version | undefined> {
return undefined;
}

let _lastServer: Version | undefined;
export async function getClient(): Promise<Version | undefined> {
return lastClient ??= await _getClient();
}

let lastServer: Version | undefined;
async function _getServer(): Promise<Version | undefined> {
await y3.env.editorReady();
if (!y3.env.editorUri) {
Expand Down Expand Up @@ -72,26 +81,89 @@ async function _getServerTest(): Promise<Version | undefined> {
}

export async function getServer(): Promise<Version | undefined> {
return _lastServer ??= await _getServer();
return lastServer ??= await _getServer();
}

export async function needUpdate(): Promise<boolean> {
let [client, server] = await Promise.all([getClient(), getServer()]);
if (!client || !server) {
return false;
}
return client.version < server.version;
return client.version !== server.version;
}

interface UpdateResult {
client?: Version,
server?: Version,
}

const _onDidChange = new vscode.EventEmitter<Version>();
export function onDidChange(callback: (version: Version) => void) {
const _onDidChange = new vscode.EventEmitter<UpdateResult>();
export function onDidChange(callback: (result: UpdateResult) => void) {
_onDidChange.event(callback);
}

setInterval(async () => {
let server = await _getServerTest();
if (server && server?.version !== _lastServer?.version) {
_lastServer = server;
_onDidChange.fire(server);
async function tryUpdateClient() {
let client = await _getClient();
if (client && client.version !== lastClient?.version) {
lastClient = client;
_onDidChange.fire({client, server: await getServer()});
}
}

async function tryUpdateServer() {
let server = await _getServer();
if (server && server.version !== lastServer?.version) {
lastServer = server;
_onDidChange.fire({client: await getClient(), server});
}
}

let dontAskUpdate = false;
export async function askUpdate(): Promise<boolean> {
if (dontAskUpdate) {
return false;
}
if (!await needUpdate()) {
return false;
}
}, 1000 * 1);
const ok = '更新';
const no = '仍要运行';
let res = await vscode.window.showInformationMessage('编辑器有新版本', {
modal: true,
detail: '如果选择“仍要运行”,那么在VSCode重启前都不会再提醒。',
}, ok, no);
if (res === ok) {
await runShell('更新编辑器', 'start', [y3.env.editorUri!.fsPath]);
return true;
} else if (res === no) {
dontAskUpdate = true;
return false;
} else {
return true;
}
}

export function init() {
setInterval(tryUpdateServer, 1000 * 60 * 5); // 5分钟检查一次
tryUpdateServer();

let lastWatchers: vscode.Disposable[] = [];
y3.env.onDidChange(async () => {
for (const watcher of lastWatchers) {
watcher.dispose();
}
lastWatchers = [];
if (!y3.env.editorUri) {
return;
}
for (const filePath of filePaths) {
const fullUri = y3.uri(y3.env.editorUri, '..', filePath);
const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(fullUri, '*'));
watcher.onDidChange(tryUpdateClient);
watcher.onDidCreate(tryUpdateClient);
watcher.onDidDelete(tryUpdateClient);

lastWatchers.push(watcher);
}
});
}

0 comments on commit 9fd91ea

Please sign in to comment.