From fde2a524d4a77ebc755b875cb528664d9a77e96e Mon Sep 17 00:00:00 2001 From: lchzh3473 Date: Wed, 11 Oct 2023 12:42:52 +0800 Subject: [PATCH] chores --- package.json | 2 +- public/index.html | 369 ++++++++++++++++++------------------ scripts/meta.json | 4 +- src/extends/format.d.ts | 5 +- src/extends/pec/rpe2json.ts | 44 +++-- src/plugins/phizone.js | 49 ++--- src/style.css | 16 +- 7 files changed, 252 insertions(+), 237 deletions(-) diff --git a/package.json b/package.json index 5b1e9c0f..574b7e89 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "sim-phi-vite", "private": true, - "version": "1.5.4.1", + "version": "1.5.4.2", "type": "module", "scripts": { "dev": "vite", diff --git a/public/index.html b/public/index.html index 2c106213..fcc9bd2c 100644 --- a/public/index.html +++ b/public/index.html @@ -1,190 +1,199 @@ + + + + (っ °Д °;)っ + + + + + + + + + + - - - - (っ °Д °;)っ - - - - - - - - - - - - - -
-
-

-

-

上传谱面和资源文件或将其打包成zip然后上传;
读取完成后调节相关参数,最后点击“播放”按钮。
播放时双击画面:左上角暂停;右上角重新开始;右下角全屏。

-
- -
- - -
-
- - - - -
-
谱面:
-
音乐:
-
图片:
-
-
宽高比: -
-
按键缩放: -
-
背景变暗: -
-
-
曲名:
-
曲师:
-
-
曲绘:
-
谱师:
-
-
难度: -
-
等级: -
-
音效音量: + + +
+
+

+

+

上传谱面和资源文件或将其打包成zip然后上传;
读取完成后调节相关参数,最后点击“播放”按钮。
播放时双击画面:左上角暂停;右上角重新开始;右下角全屏。

+
+ +
+ + +
-
-
-
-
-
-
-
-
-
-
谱面镜像: + + + + +
+
谱面:
+
音乐:
+
图片:
+
+
+ 宽高比: +
+
+ 按键缩放: +
+
+ 背景变暗: +
+
+
曲名:
+
曲师:
+
+
曲绘:
+
谱师:
+
+
+ 难度: +
+
+ 等级: +
+
+ 音效音量: +
+
+
+
+
+
+
+
+
+
+
+ 谱面镜像: +
+
+ 音乐变速: +
+
+
谱面延时(ms):
+
+ + +
-
音乐变速: +
初始化...
+
+ + + + +
+
GitHub: lchzh3473/sim-phi
+
-
-
谱面延时(ms):
-
- - +
+
+
+ +
+
+
+
-
-
初始化...
-
- -
-
GitHub: lchzh3473/sim-phi
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
+
+ +
+
+
+
+
- -
- - - \ No newline at end of file + + diff --git a/scripts/meta.json b/scripts/meta.json index a48af017..6db05323 100644 --- a/scripts/meta.json +++ b/scripts/meta.json @@ -1,5 +1,5 @@ { - "version": "1.5.4.1", + "version": "1.5.4.2", "pubdate": 1611795955, - "lastupdate": 1696489055 + "lastupdate": 1696999322 } diff --git a/src/extends/format.d.ts b/src/extends/format.d.ts index accadf1c..586dc104 100644 --- a/src/extends/format.d.ts +++ b/src/extends/format.d.ts @@ -27,9 +27,10 @@ interface JudgeLine { interface SpeedEvent { startTime: number; endTime: number; - floorPosition: number; - floorPosition2?: number; // FIXME: float32 value: number; + floorPosition: number; + floorPosition2?: number; // float32 + floorPositionMin?: number; } interface JudgeLineEvent { startTime: number; diff --git a/src/extends/pec/rpe2json.ts b/src/extends/pec/rpe2json.ts index 67db26df..bbe68f89 100644 --- a/src/extends/pec/rpe2json.ts +++ b/src/extends/pec/rpe2json.ts @@ -295,6 +295,7 @@ interface NoteRPE1 { speed: number; isAbove: boolean; isFake: boolean; + isHidden: boolean; } class LineRPE1 { public bpm: number; @@ -317,8 +318,8 @@ class LineRPE1 { this.merged = false; if (!isNaN(bpm)) this.bpm = bpm; } - public pushNote(type: number, time: number, positionX: number, holdTime: number, speed: number, isAbove: boolean, isFake: boolean) { - this.notes.push({ type, time, positionX, holdTime, speed, isAbove, isFake }); + public pushNote(type: number, time: number, positionX: number, holdTime: number, speed: number, isAbove: boolean, isFake: boolean, isHide: boolean) { + this.notes.push({ type, time, positionX, holdTime, speed, isAbove, isFake, isHidden: isHide }); } public setId(id = NaN) { this.id = id } public setFather(fatherLine: LineRPE1 | null) { this.father = fatherLine } @@ -406,38 +407,55 @@ class LineRPE1 { } // 添加floorPosition let floorPos = 0; + let minPos = 0; const speedEvents = this.speedEvents!; for (let i = 0; i < speedEvents.length; i++) { const startTime = Math.max(speedEvents[i].time, 0); const endTime = i < speedEvents.length - 1 ? speedEvents[i + 1].time : 1e9; const value = speedEvents[i].value * 2 / 9; - const floorPosition = floorPos; + result.speedEvents.push({ startTime, endTime, value, floorPosition: floorPos, floorPositionMin: minPos }); floorPos += (endTime - startTime) * value / this.bpm * 1.875; floorPos = Math.fround(floorPos); - result.speedEvents.push({ startTime, endTime, value, floorPosition }); + minPos = Math.min(minPos, floorPos); } // 处理notes const sortFn = (a: { time: number }, b: { time: number }) => a.time - b.time; - for (const i of this.notes.sort(sortFn)) { - const { time } = i; + const getPositionValues = (time: number) => { let v1 = 0; let v2 = 0; let v3 = 0; + let vmin = 0; for (const e of result.speedEvents) { if (time > e.endTime) continue; if (time < e.startTime) break; v1 = e.floorPosition; v2 = e.value; v3 = time - e.startTime; + vmin = e.floorPositionMin!; } + return { v1, v4: v2 * v3, vmin }; + }; + const getHoldSpeedValue = (time: number, holdTime: number) => { + const start = getPositionValues(time); + const end = getPositionValues(time + holdTime); + return ((end.v1 - start.v1) / 1.875 * this.bpm + (end.v4 - start.v4)) / holdTime; + }; + for (const i of this.notes.sort(sortFn)) { + const { v1, v4, vmin } = getPositionValues(i.time); + const speedFactor = i.type === 3 ? getHoldSpeedValue(i.time, i.holdTime) : 1; + const floorPosition = Math.fround(v1 + v4 / this.bpm * 1.875); const note = { type: i.type, - time: time + (i.isFake ? 1e9 : 0), + time: i.time + (i.isFake ? 1e9 : 0), positionX: i.positionX, holdTime: i.holdTime, - speed: i.speed * (i.type === 3 ? v2 : 1), - floorPosition: Math.fround(v1 + v2 * v3 / this.bpm * 1.875) + speed: i.speed * speedFactor, + floorPosition }; + if (i.isHidden) { + note.speed = 0; + note.floorPosition = Math.min(vmin, floorPosition) - 1; + } if (i.isAbove) { result.notesAbove.push(note); if (i.isFake) continue; @@ -554,18 +572,18 @@ export function parse(pec: string, filename: string): { if (i.notes) { for (const note of i.notes) { if (note.alpha === undefined) note.alpha = 255; - // if (note.above !== 1 && note.above !== 2) ({code:1,name:'NoteSideWarning',message:`检测到非法方向:${note.above}(将被视为2)\n位于:"${JSON.stringify(note)}"`}); - if (note.isFake !== 0) warn(1, 'FakeNoteWarning', `检测到FakeNote(可能无法正常显示)\n位于:"${JSON.stringify(note)}"`); + if (note.above !== 1 && note.above !== 2) warn(1, 'NoteSideWarning', `检测到非法方向:${note.above}(将被视为2)\n位于:"${JSON.stringify(note)}"`); + if (note.isFake !== 0) warn(1, 'NoteFakeWarning', `检测到FakeNote(可能无法正常显示)\n位于:"${JSON.stringify(note)}"`); if (note.size !== 1) warn(1, 'ImplementionWarning', `未兼容size=${note.size}(可能无法正常显示)\n位于:"${JSON.stringify(note)}"`); if (note.yOffset !== 0) warn(1, 'ImplementionWarning', `未兼容yOffset=${note.yOffset}(可能无法正常显示)\n位于:"${JSON.stringify(note)}"`); if (note.visibleTime !== 999999) warn(1, 'ImplementionWarning', `未兼容visibleTime=${note.visibleTime}(可能无法正常显示)\n位于:"${JSON.stringify(note)}"`); - if (note.alpha !== 255) warn(1, 'ImplementionWarning', `未兼容alpha=${note.alpha}(可能无法正常显示)\n位于:"${JSON.stringify(note)}"`); + if (note.alpha !== 255 && note.alpha !== 0) warn(1, 'ImplementionWarning', `未兼容alpha=${note.alpha}(可能无法正常显示)\n位于:"${JSON.stringify(note)}"`); const type = [0, 1, 4, 2, 3].indexOf(note.type); const time = bpmList.calc2(note.startTime); const holdTime = bpmList.calc2(note.endTime) - time; const { speed } = note; const positionX = note.positionX / 75.375; - lineRPE.pushNote(type, time, positionX, holdTime, speed, note.above === 1, note.isFake !== 0); + lineRPE.pushNote(type, time, positionX, holdTime, speed, note.above === 1, note.isFake !== 0, note.alpha === 0); } } for (const e of i.eventLayers) { diff --git a/src/plugins/phizone.js b/src/plugins/phizone.js index ee8e2804..12e06bf1 100644 --- a/src/plugins/phizone.js +++ b/src/plugins/phizone.js @@ -23,39 +23,41 @@ const getSongsUrlByIndex = (index = 0) => `${host}/songs/?perpage=1&page=${index const getChartsUrlByIndex = (index = 0) => `${host}/charts/?perpage=1&page=${index}`; const getChartsUrlByUUID = (id = '') => `${host}/songs/${id}/charts/`; const getRandomChartUrl = () => `${host}/charts/random/?rangeFormat=0&rangeFormat=1`; -const ver = 'PhiZone API v0.8.3'; +const ver = 'PhiZone API v0.8.4'; // eslint-disable-next-line no-alert const vprompt = str => prompt(`${ver}\n${str}`); const valert = str => hook.toast(`${ver}\n${str}`); +const msgNetErr = err => { + valert(`无法连接至服务器\n错误代码:${err.message}`); + sendText('无法连接至服务器'); +}; +const msgNoChart = id => { + valert(`歌曲ID ${id} 对应的谱面不存在`); + sendText(`歌曲ID ${id} 对应的谱面不存在`); +}; async function dialog(num) { const id = num || vprompt('请输入歌曲ID'); if (id === '' || id === null) { valert('未输入歌曲ID,已取消操作'); return } - const data = await query(id).catch(err => { - valert(`无法连接至服务器\n错误代码:${err.message}`); - sendText('无法连接至服务器'); - }); + const data = await query(id).catch(msgNetErr); console.log(data); if (!data) return; - if (!data.charts.length) { valert(`歌曲ID ${id} 对应的谱面不存在`); return } + if (!data.charts.length) { msgNoChart(id); return } await readData(data); } async function dialogc(num) { const id = num || vprompt('请输入谱面ID'); if (id === '' || id === null) { valert('未输入谱面ID,已取消操作'); return } - const data = await queryChart(id).catch(err => { - valert(`无法连接至服务器\n错误代码:${err.message}`); - sendText('无法连接至服务器'); - }); + const data = await queryChart(id).catch(msgNetErr); console.log(data); if (!data) return; - if (!data.charts.length) { valert(`谱面ID ${id} 对应的谱面不存在`); return } + if (!data.charts.length) { msgNoChart(id); return } await readData(data); } async function random() { - const data = await queryRandom().catch(err => valert(`无法连接至服务器\n错误代码:${err.message}`)); + const data = await queryRandom().catch(msgNetErr); console.log(data); if (!data) return; - if (!data.charts.length) { valert(`歌曲ID ${''} 对应的谱面不存在`); return } + if (!data.charts.length) { msgNoChart(''); return } await readData(data); } async function query(id) { @@ -237,32 +239,17 @@ Object.defineProperty(Downloader.prototype, 'total', { get() { return values.reduce((total, xhr) => total + Math.max(xhr.event.loaded, xhr.event.total), 0); } }); function getChartOffset(id) { - if (id === '0ada5f8d-7f1d-426e-b53d-747d4489e255') return 100; // 29 - if (id === '5201e181-b5d1-4931-9785-e78cbed0758e') return 50; // 34 - if (id === '8747c9b5-9029-499d-b1d5-59bd46e2522f') return 150; // 35 - if (id === 'ccf6522f-d746-4b76-9b3b-09d6534fd99e') return 50; // 38 - if (id === '5d17fa22-51da-48e3-b56d-29ed782d830b') return 175; // 39 if (id === '67b8c0fd-4879-41e3-af04-6dc8f41ddcd1') return -500; // 48 - if (id === 'e15c5743-fbb1-4d36-9821-43208a75bf07') return 100; // 51 - if (id === '2eb9e940-4350-4509-a244-068abd937f44') return 50; // 53 + if (id === '2eb9e940-4350-4509-a244-068abd937f44') return -50; // 53 if (id === '026c8905-6f24-421c-a594-e5f9bf1d053a') return 150; // 54 if (id === '71acb2d4-225e-4b0a-989c-660f4c075542') return 175; // 57 if (id === '165119b8-7074-4106-bb23-27a8fb99c0c6') return 150; // 58 - if (id === '846587d2-0ff2-40ca-b42b-3568cef08e48') return 250; // 59 - if (id === '74585cab-6b6f-4633-9c3d-4dfa9900cafd') return -100; // 61 - if (id === '108254a0-a756-4200-8391-1f47bb7707aa') return -50; // 68 + if (id === '846587d2-0ff2-40ca-b42b-3568cef08e48') return -25; // 59 + if (id === '74585cab-6b6f-4633-9c3d-4dfa9900cafd') return 75; // 61 if (id === '8c4d638a-a1aa-4e29-a0d2-2f3a2cb7e69c') return 300; // 69 - if (id === 'e29e6b87-796f-4518-ac33-d9db79bbc103') return 200; // 70 - if (id === '7457a0a7-5d50-4e5e-b5a5-6049100a168e') return 200; // 72 if (id === 'c4dc62c4-7bed-4f39-b6ed-451ecdcb9b6b') return 250; // 73 - if (id === '53e2ca24-2212-4795-be30-1a80cebbc339') return 250; // 76 - if (id === 'af635f4b-df9c-42ad-9f8d-e20c0e2aebad') return 400; // 77 - if (id === 'e4307062-420a-49a2-8515-b22375e7f6c4') return -50; // 79 if (id === 'f0b1e2eb-f7f8-42ec-bcb3-6a717147ad4e') return 225; // 80 - if (id === '918a8854-04be-47e3-bfae-62699d193fee') return 200; // 82 - if (id === 'ed0d5555-7573-4b9d-a491-b22aeab66da7') return 200; // 83 if (id === 'd7ad0802-22e1-4efc-8bba-4cfe074d2a95') return 200; // 85 - if (id === 'f2398611-f145-45f5-b4f9-78be5f97fa86') return 175; // 86 if (id === '7be304a2-74cc-48a7-80bb-98de40cd814d') return -25; // 88 if (id === '232ec440-647e-4319-96c2-17e97f4ea55d') return 150; // 90 if (id === '11eae627-ff9e-48fe-8c9f-2d49d6e34221') return -100; // 91 diff --git a/src/style.css b/src/style.css index facdce87..2edbff17 100644 --- a/src/style.css +++ b/src/style.css @@ -23,7 +23,7 @@ body { } #stage i { - font-family: icomoon; + font-family: 'Material Icons'; font-style: normal; color: #fff; font-size: 4vmin; @@ -92,14 +92,14 @@ body { visibility: visible; } -#uploader-select>label { +#uploader-select > label { font-size: 0.9em; padding: 0.15em 0.15em 0.15em 0; text-align: left; padding: 0.2em 0.6em; } -#uploader-select>label:hover { +#uploader-select > label:hover { background-color: #c9e5ca; } @@ -134,7 +134,7 @@ body { pointer-events: none; } -.cover-view>* { +.cover-view > * { pointer-events: initial; } @@ -146,7 +146,7 @@ body { overflow: scroll; } -#view-cfg>div { +#view-cfg > div { padding: 0.5em 0; display: flex; justify-content: center; @@ -200,7 +200,7 @@ body { flex-wrap: nowrap; } -.cover-view[qwq]>.view-content { +.cover-view[qwq] > .view-content { flex-grow: 1; } @@ -260,6 +260,6 @@ body { padding-bottom: 0.5em; } -.bm-item:last-child>.bm-rbtn { +.bm-item:last-child > .bm-rbtn { padding-bottom: 0; -} \ No newline at end of file +}