osu-play 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/osu-play.js +1 -1
- package/dist/cli/main.cjs +400 -0
- package/dist/cli/main.cjs.map +1 -0
- package/dist/cli/main.d.cts +3 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +365 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/mod.cjs +367 -0
- package/dist/mod.cjs.map +1 -0
- package/dist/mod.d.cts +121 -0
- package/dist/mod.d.ts +121 -0
- package/dist/mod.js +335 -0
- package/dist/mod.js.map +1 -0
- package/package.json +16 -4
- package/tsconfig.json +7 -3
- package/src/main.ts +0 -72
- package/src/realm/mod.ts +0 -54
- package/src/realm/schema/beatmap.ts +0 -85
- package/src/realm/schema/beatmapMetadata.ts +0 -33
- package/src/realm/schema/beatmapSet.ts +0 -36
- package/src/realm/schema/mod.ts +0 -7
- package/src/realm/schema/realmFile.ts +0 -15
- package/src/realm/schema/realmNamedFileUsage.ts +0 -19
- package/src/realm/schema/realmUser.ts +0 -21
- package/src/utils/mod.ts +0 -81
package/dist/mod.js
ADDED
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
// src/utils/mod.ts
|
|
8
|
+
var mod_exports = {};
|
|
9
|
+
__export(mod_exports, {
|
|
10
|
+
getConfigDir: () => getConfigDir,
|
|
11
|
+
getDataDir: () => getDataDir,
|
|
12
|
+
getRealmDBPath: () => getRealmDBPath
|
|
13
|
+
});
|
|
14
|
+
import path from "path";
|
|
15
|
+
import { copyFileSync, existsSync, mkdirSync } from "fs";
|
|
16
|
+
function getDataDir() {
|
|
17
|
+
switch (process.platform) {
|
|
18
|
+
case "linux":
|
|
19
|
+
case "openbsd":
|
|
20
|
+
case "freebsd": {
|
|
21
|
+
const xdg = process.env["XDG_DATA_HOME"];
|
|
22
|
+
if (xdg)
|
|
23
|
+
return xdg;
|
|
24
|
+
const home = process.env["HOME"];
|
|
25
|
+
if (home)
|
|
26
|
+
return path.join(home, ".local", "share");
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case "darwin": {
|
|
30
|
+
const home = process.env["HOME"];
|
|
31
|
+
if (home)
|
|
32
|
+
return path.join(home, "Library", "Application Support");
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
case "win32":
|
|
36
|
+
return process.env["LOCALAPPDATA"] ?? null;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function getConfigDir() {
|
|
41
|
+
switch (process.platform) {
|
|
42
|
+
case "openbsd":
|
|
43
|
+
case "freebsd":
|
|
44
|
+
case "linux": {
|
|
45
|
+
const xdg = process.env["XDG_CONFIG_HOME"];
|
|
46
|
+
if (xdg)
|
|
47
|
+
return xdg;
|
|
48
|
+
const home = process.env["HOME"];
|
|
49
|
+
if (home)
|
|
50
|
+
return path.join(home, ".config");
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case "darwin": {
|
|
54
|
+
const home = process.env["HOME"];
|
|
55
|
+
if (home)
|
|
56
|
+
return path.join(home, "Library", "Preferences");
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
case "win32":
|
|
60
|
+
return process.env["APPDATA"] ?? null;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function getRealmDBPath(appConfigDir, osuDataDir, reload = false) {
|
|
65
|
+
const localDBPath = path.join(appConfigDir, "client.realm");
|
|
66
|
+
if (!reload && existsSync(localDBPath))
|
|
67
|
+
return localDBPath;
|
|
68
|
+
const osuDBPath = path.join(
|
|
69
|
+
osuDataDir || getDataDir() || ".",
|
|
70
|
+
"osu",
|
|
71
|
+
"client.realm"
|
|
72
|
+
);
|
|
73
|
+
if (existsSync(osuDBPath)) {
|
|
74
|
+
console.log(
|
|
75
|
+
`[getRealmDBPath]: ${osuDBPath} is being imported from osu!lazer to ${localDBPath}`
|
|
76
|
+
);
|
|
77
|
+
mkdirSync(appConfigDir);
|
|
78
|
+
copyFileSync(osuDBPath, localDBPath);
|
|
79
|
+
return localDBPath;
|
|
80
|
+
} else {
|
|
81
|
+
console.log(`[getRealmDBPath]: ${osuDBPath} not found`);
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// src/realm/mod.ts
|
|
87
|
+
var mod_exports2 = {};
|
|
88
|
+
__export(mod_exports2, {
|
|
89
|
+
getLazerDB: () => getLazerDB,
|
|
90
|
+
getNamedFileHash: () => getNamedFileHash,
|
|
91
|
+
hashedFilePath: () => hashedFilePath
|
|
92
|
+
});
|
|
93
|
+
import Realm7 from "realm";
|
|
94
|
+
import path2 from "path";
|
|
95
|
+
|
|
96
|
+
// src/realm/schema/beatmap.ts
|
|
97
|
+
import Realm from "realm";
|
|
98
|
+
var Beatmap = class extends Realm.Object {
|
|
99
|
+
ID;
|
|
100
|
+
DifficultyName;
|
|
101
|
+
Ruleset;
|
|
102
|
+
Difficulty;
|
|
103
|
+
Metadata;
|
|
104
|
+
UserSettings;
|
|
105
|
+
BeatmapSet;
|
|
106
|
+
Status;
|
|
107
|
+
OnlineID;
|
|
108
|
+
Length;
|
|
109
|
+
BPM;
|
|
110
|
+
Hash;
|
|
111
|
+
StarRating;
|
|
112
|
+
MD5Hash;
|
|
113
|
+
OnlineMD5Hash;
|
|
114
|
+
LastLocalUpdate;
|
|
115
|
+
LastOnlineUpdate;
|
|
116
|
+
Hidden;
|
|
117
|
+
AudioLeadIn;
|
|
118
|
+
StackLeniency;
|
|
119
|
+
SpecialStyle;
|
|
120
|
+
LetterboxInBreaks;
|
|
121
|
+
WidescreenStoryboard;
|
|
122
|
+
EpilepsyWarning;
|
|
123
|
+
SamplesMatchPlaybackRate;
|
|
124
|
+
LastPlayed;
|
|
125
|
+
DistanceSpacing;
|
|
126
|
+
BeatDivisor;
|
|
127
|
+
GridSize;
|
|
128
|
+
TimelineZoom;
|
|
129
|
+
EditorTimestamp;
|
|
130
|
+
CountdownOffset;
|
|
131
|
+
static schema = {
|
|
132
|
+
name: "Beatmap",
|
|
133
|
+
primaryKey: "ID",
|
|
134
|
+
properties: {
|
|
135
|
+
ID: { type: "uuid", default: "" },
|
|
136
|
+
DifficultyName: { type: "string", default: "", optional: true },
|
|
137
|
+
// Ruleset: { type: "object", objectType: "Ruleset", default: null },
|
|
138
|
+
// Difficulty: { type: "object", objectType: "BeatmapDifficulty", default: null },
|
|
139
|
+
Metadata: {
|
|
140
|
+
type: "object",
|
|
141
|
+
objectType: "BeatmapMetadata",
|
|
142
|
+
default: null
|
|
143
|
+
},
|
|
144
|
+
// UserSettings: { type: "object", objectType: "BeatmapUserSettings", default: null },
|
|
145
|
+
BeatmapSet: { type: "object", objectType: "BeatmapSet", default: null },
|
|
146
|
+
Status: { type: "int", default: -3 },
|
|
147
|
+
OnlineID: { type: "int", default: -1 },
|
|
148
|
+
Length: { type: "double", default: 0 },
|
|
149
|
+
BPM: { type: "double", default: 0 },
|
|
150
|
+
Hash: { type: "string", default: "", optional: true },
|
|
151
|
+
StarRating: { type: "double", default: -1 },
|
|
152
|
+
MD5Hash: { type: "string", default: "", optional: true },
|
|
153
|
+
OnlineMD5Hash: {
|
|
154
|
+
type: "string",
|
|
155
|
+
default: "",
|
|
156
|
+
optional: true
|
|
157
|
+
},
|
|
158
|
+
LastLocalUpdate: { type: "date", optional: true },
|
|
159
|
+
LastOnlineUpdate: { type: "date", optional: true },
|
|
160
|
+
Hidden: { type: "bool", default: false },
|
|
161
|
+
AudioLeadIn: { type: "double", default: 0 },
|
|
162
|
+
StackLeniency: { type: "float", default: 0.7 },
|
|
163
|
+
SpecialStyle: { type: "bool", default: false },
|
|
164
|
+
LetterboxInBreaks: { type: "bool", default: false },
|
|
165
|
+
WidescreenStoryboard: { type: "bool", default: false },
|
|
166
|
+
EpilepsyWarning: { type: "bool", default: false },
|
|
167
|
+
SamplesMatchPlaybackRate: { type: "bool", default: false },
|
|
168
|
+
LastPlayed: { type: "date", optional: true },
|
|
169
|
+
DistanceSpacing: { type: "double", default: 0 },
|
|
170
|
+
BeatDivisor: { type: "int", default: 0 },
|
|
171
|
+
GridSize: { type: "int", default: 0 },
|
|
172
|
+
TimelineZoom: { type: "double", default: 0 },
|
|
173
|
+
EditorTimestamp: { type: "double", optional: true },
|
|
174
|
+
CountdownOffset: { type: "int", default: 0 }
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// src/realm/schema/beatmapMetadata.ts
|
|
180
|
+
import Realm2 from "realm";
|
|
181
|
+
var BeatmapMetadata = class extends Realm2.Object {
|
|
182
|
+
Title;
|
|
183
|
+
TitleUnicode;
|
|
184
|
+
Artist;
|
|
185
|
+
ArtistUnicode;
|
|
186
|
+
Author;
|
|
187
|
+
Source;
|
|
188
|
+
Tags;
|
|
189
|
+
PreviewTime;
|
|
190
|
+
AudioFile;
|
|
191
|
+
BackgroundFile;
|
|
192
|
+
static schema = {
|
|
193
|
+
name: "BeatmapMetadata",
|
|
194
|
+
properties: {
|
|
195
|
+
Title: { type: "string", default: "", optional: true },
|
|
196
|
+
TitleUnicode: { type: "string", default: "", optional: true },
|
|
197
|
+
Artist: { type: "string", default: "", optional: true },
|
|
198
|
+
ArtistUnicode: { type: "string", default: "", optional: true },
|
|
199
|
+
Author: { type: "object", objectType: "RealmUser", default: null },
|
|
200
|
+
Source: { type: "string", default: "", optional: true },
|
|
201
|
+
Tags: { type: "string", default: "", optional: true },
|
|
202
|
+
PreviewTime: { type: "int", default: 0 },
|
|
203
|
+
AudioFile: { type: "string", default: "", optional: true },
|
|
204
|
+
BackgroundFile: { type: "string", default: "", optional: true }
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
// src/realm/schema/beatmapSet.ts
|
|
210
|
+
import Realm3 from "realm";
|
|
211
|
+
var BeatmapSet = class extends Realm3.Object {
|
|
212
|
+
ID;
|
|
213
|
+
OnlineID;
|
|
214
|
+
DateAdded;
|
|
215
|
+
DateSubmitted;
|
|
216
|
+
DateRanked;
|
|
217
|
+
Beatmaps;
|
|
218
|
+
Files;
|
|
219
|
+
Status;
|
|
220
|
+
DeletePending;
|
|
221
|
+
Hash;
|
|
222
|
+
Protected;
|
|
223
|
+
static schema = {
|
|
224
|
+
name: "BeatmapSet",
|
|
225
|
+
primaryKey: "ID",
|
|
226
|
+
properties: {
|
|
227
|
+
ID: { type: "uuid", default: "" },
|
|
228
|
+
OnlineID: { type: "int", default: -1 },
|
|
229
|
+
DateAdded: { type: "date" },
|
|
230
|
+
DateSubmitted: { type: "date", optional: true },
|
|
231
|
+
DateRanked: { type: "date", optional: true },
|
|
232
|
+
Beatmaps: { type: "list", objectType: "Beatmap", default: [] },
|
|
233
|
+
Files: { type: "list", objectType: "RealmNamedFileUsage", default: [] },
|
|
234
|
+
Status: { type: "int", default: -3 },
|
|
235
|
+
DeletePending: { type: "bool", default: false },
|
|
236
|
+
Hash: { type: "string", default: "", optional: true },
|
|
237
|
+
Protected: { type: "bool", default: false }
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
};
|
|
241
|
+
|
|
242
|
+
// src/realm/schema/realmFile.ts
|
|
243
|
+
import Realm4 from "realm";
|
|
244
|
+
var RealmFile = class extends Realm4.Object {
|
|
245
|
+
Hash;
|
|
246
|
+
static schema = {
|
|
247
|
+
name: "File",
|
|
248
|
+
primaryKey: "Hash",
|
|
249
|
+
properties: {
|
|
250
|
+
Hash: { type: "string", default: "", optional: true }
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
// src/realm/schema/realmUser.ts
|
|
256
|
+
import Realm5 from "realm";
|
|
257
|
+
var RealmUser = class extends Realm5.Object {
|
|
258
|
+
OnlineID;
|
|
259
|
+
Username;
|
|
260
|
+
CountryCode;
|
|
261
|
+
static embedded = true;
|
|
262
|
+
static schema = {
|
|
263
|
+
name: "RealmUser",
|
|
264
|
+
embedded: true,
|
|
265
|
+
properties: {
|
|
266
|
+
OnlineID: { type: "int", default: 1 },
|
|
267
|
+
Username: { type: "string", default: "", optional: true },
|
|
268
|
+
CountryCode: { type: "string", optional: true }
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
// src/realm/schema/realmNamedFileUsage.ts
|
|
274
|
+
import Realm6 from "realm";
|
|
275
|
+
var RealmNamedFileUsage = class extends Realm6.Object {
|
|
276
|
+
File;
|
|
277
|
+
Filename;
|
|
278
|
+
static embedded = true;
|
|
279
|
+
static schema = {
|
|
280
|
+
name: "RealmNamedFileUsage",
|
|
281
|
+
embedded: true,
|
|
282
|
+
properties: {
|
|
283
|
+
File: "File",
|
|
284
|
+
Filename: { type: "string", optional: true }
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// src/realm/mod.ts
|
|
290
|
+
var getLazerDB = async (realmDBPath) => {
|
|
291
|
+
const realm = await Realm7.open({
|
|
292
|
+
schema: [
|
|
293
|
+
BeatmapSet,
|
|
294
|
+
RealmFile,
|
|
295
|
+
RealmNamedFileUsage,
|
|
296
|
+
Beatmap,
|
|
297
|
+
BeatmapMetadata,
|
|
298
|
+
RealmUser
|
|
299
|
+
],
|
|
300
|
+
path: realmDBPath,
|
|
301
|
+
schemaVersion: 36,
|
|
302
|
+
onMigration: (oldRealm, newRealm) => {
|
|
303
|
+
console.log(
|
|
304
|
+
`[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
return realm;
|
|
309
|
+
};
|
|
310
|
+
var hashedFilePath = (hash) => {
|
|
311
|
+
const dataDir = getDataDir();
|
|
312
|
+
if (!dataDir)
|
|
313
|
+
return null;
|
|
314
|
+
return path2.join(
|
|
315
|
+
dataDir,
|
|
316
|
+
"osu",
|
|
317
|
+
"files",
|
|
318
|
+
hash.slice(0, 1),
|
|
319
|
+
hash.slice(0, 2),
|
|
320
|
+
hash
|
|
321
|
+
);
|
|
322
|
+
};
|
|
323
|
+
var getNamedFileHash = (fileName, beatmapSet) => {
|
|
324
|
+
const files = beatmapSet.Files;
|
|
325
|
+
for (const file of files) {
|
|
326
|
+
if (file.Filename == fileName)
|
|
327
|
+
return file.File.Hash;
|
|
328
|
+
}
|
|
329
|
+
return void 0;
|
|
330
|
+
};
|
|
331
|
+
export {
|
|
332
|
+
mod_exports2 as lazer,
|
|
333
|
+
mod_exports as utils
|
|
334
|
+
};
|
|
335
|
+
//# sourceMappingURL=mod.js.map
|
package/dist/mod.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils/mod.ts","../src/realm/mod.ts","../src/realm/schema/beatmap.ts","../src/realm/schema/beatmapMetadata.ts","../src/realm/schema/beatmapSet.ts","../src/realm/schema/realmFile.ts","../src/realm/schema/realmUser.ts","../src/realm/schema/realmNamedFileUsage.ts"],"sourcesContent":["import path from \"node:path\";\nimport { copyFileSync, existsSync, mkdirSync } from \"node:fs\";\n\nexport function getDataDir(): string | null {\n switch (process.platform) {\n case \"linux\":\n case \"openbsd\":\n case \"freebsd\": {\n const xdg = process.env[\"XDG_DATA_HOME\"];\n if (xdg) return xdg;\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \".local\", \"share\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \"Library\", \"Application Support\");\n break;\n }\n\n case \"win32\":\n return process.env[\"LOCALAPPDATA\"] ?? null;\n }\n\n return null;\n}\n\nexport function getConfigDir(): string | null {\n switch (process.platform) {\n case \"openbsd\":\n case \"freebsd\":\n case \"linux\": {\n const xdg = process.env[\"XDG_CONFIG_HOME\"];\n if (xdg) return xdg;\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \".config\");\n break;\n }\n\n case \"darwin\": {\n const home = process.env[\"HOME\"];\n if (home) return path.join(home, \"Library\", \"Preferences\");\n break;\n }\n\n case \"win32\":\n return process.env[\"APPDATA\"] ?? null;\n }\n\n return null;\n}\n\n/**\n * Get Realm for the app, import to the config if it doesn't exist\n */\nexport function getRealmDBPath(\n appConfigDir: string,\n osuDataDir?: string,\n reload: boolean = false,\n) {\n const localDBPath = path.join(appConfigDir, \"client.realm\");\n if (!reload && existsSync(localDBPath)) return localDBPath;\n\n const osuDBPath = path.join(\n osuDataDir || getDataDir()! || \".\",\n \"osu\",\n \"client.realm\",\n );\n if (existsSync(osuDBPath)) {\n console.log(\n `[getRealmDBPath]: ${osuDBPath} is being imported from osu!lazer to ${localDBPath}`,\n );\n mkdirSync(appConfigDir);\n copyFileSync(osuDBPath, localDBPath);\n return localDBPath;\n } else {\n console.log(`[getRealmDBPath]: ${osuDBPath} not found`);\n return null;\n }\n}\n","import Realm from \"realm\";\nimport path from \"node:path\";\nimport { getDataDir } from \"../utils/mod.js\";\nimport {\n Beatmap,\n BeatmapMetadata,\n BeatmapSet,\n RealmFile,\n RealmNamedFileUsage,\n RealmUser,\n} from \"./schema/mod.js\";\n\nexport const getLazerDB = async (realmDBPath: string) => {\n const realm = await Realm.open({\n schema: [\n BeatmapSet,\n RealmFile,\n RealmNamedFileUsage,\n Beatmap,\n BeatmapMetadata,\n RealmUser,\n ],\n path: realmDBPath,\n schemaVersion: 36,\n onMigration: (oldRealm, newRealm) => {\n console.log(\n `[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`,\n );\n },\n });\n\n return realm;\n};\n\nexport const hashedFilePath = (hash: string) => {\n const dataDir = getDataDir();\n if (!dataDir) return null;\n return path.join(\n dataDir,\n \"osu\",\n \"files\",\n hash.slice(0, 1),\n hash.slice(0, 2),\n hash,\n );\n};\n\nexport const getNamedFileHash = (fileName: string, beatmapSet: BeatmapSet) => {\n const files = beatmapSet.Files;\n for (const file of files) {\n if (file.Filename == fileName) return file.File.Hash;\n }\n return undefined;\n};\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { BeatmapMetadata } from \"./beatmapMetadata.js\";\n\nexport class Beatmap extends Realm.Object<Beatmap> {\n ID!: string;\n DifficultyName?: string;\n Ruleset!: any;\n Difficulty!: any;\n Metadata!: BeatmapMetadata;\n UserSettings!: any;\n BeatmapSet!: any;\n Status!: number;\n OnlineID!: number;\n Length!: number;\n BPM!: number;\n Hash?: string;\n StarRating!: number;\n MD5Hash?: string;\n OnlineMD5Hash?: string;\n LastLocalUpdate?: Date;\n LastOnlineUpdate?: Date;\n Hidden!: boolean;\n AudioLeadIn!: number;\n StackLeniency!: number;\n SpecialStyle!: boolean;\n LetterboxInBreaks!: boolean;\n WidescreenStoryboard!: boolean;\n EpilepsyWarning!: boolean;\n SamplesMatchPlaybackRate!: boolean;\n LastPlayed?: Date;\n DistanceSpacing!: number;\n BeatDivisor!: number;\n GridSize!: number;\n TimelineZoom!: number;\n EditorTimestamp?: number;\n CountdownOffset!: number;\n\n static schema: ObjectSchema = {\n name: \"Beatmap\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n DifficultyName: { type: \"string\", default: \"\", optional: true },\n // Ruleset: { type: \"object\", objectType: \"Ruleset\", default: null },\n // Difficulty: { type: \"object\", objectType: \"BeatmapDifficulty\", default: null },\n Metadata: {\n type: \"object\",\n objectType: \"BeatmapMetadata\",\n default: null,\n },\n // UserSettings: { type: \"object\", objectType: \"BeatmapUserSettings\", default: null },\n BeatmapSet: { type: \"object\", objectType: \"BeatmapSet\", default: null },\n Status: { type: \"int\", default: -3 },\n OnlineID: { type: \"int\", default: -1 },\n Length: { type: \"double\", default: 0 },\n BPM: { type: \"double\", default: 0 },\n Hash: { type: \"string\", default: \"\", optional: true },\n StarRating: { type: \"double\", default: -1 },\n MD5Hash: { type: \"string\", default: \"\", optional: true },\n OnlineMD5Hash: {\n type: \"string\",\n default: \"\",\n optional: true,\n },\n LastLocalUpdate: { type: \"date\", optional: true },\n LastOnlineUpdate: { type: \"date\", optional: true },\n Hidden: { type: \"bool\", default: false },\n AudioLeadIn: { type: \"double\", default: 0 },\n StackLeniency: { type: \"float\", default: 0.7 },\n SpecialStyle: { type: \"bool\", default: false },\n LetterboxInBreaks: { type: \"bool\", default: false },\n WidescreenStoryboard: { type: \"bool\", default: false },\n EpilepsyWarning: { type: \"bool\", default: false },\n SamplesMatchPlaybackRate: { type: \"bool\", default: false },\n LastPlayed: { type: \"date\", optional: true },\n DistanceSpacing: { type: \"double\", default: 0 },\n BeatDivisor: { type: \"int\", default: 0 },\n GridSize: { type: \"int\", default: 0 },\n TimelineZoom: { type: \"double\", default: 0 },\n EditorTimestamp: { type: \"double\", optional: true },\n CountdownOffset: { type: \"int\", default: 0 },\n },\n };\n}\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmUser } from \"./realmUser.js\";\n\nexport class BeatmapMetadata extends Realm.Object<BeatmapMetadata> {\n Title?: string;\n TitleUnicode?: string;\n Artist?: string;\n ArtistUnicode?: string;\n Author?: RealmUser;\n Source?: string;\n Tags?: string;\n PreviewTime?: number;\n AudioFile?: string;\n BackgroundFile?: string;\n\n static schema: ObjectSchema = {\n name: \"BeatmapMetadata\",\n properties: {\n Title: { type: \"string\", default: \"\", optional: true },\n TitleUnicode: { type: \"string\", default: \"\", optional: true },\n Artist: { type: \"string\", default: \"\", optional: true },\n ArtistUnicode: { type: \"string\", default: \"\", optional: true },\n Author: { type: \"object\", objectType: \"RealmUser\", default: null },\n Source: { type: \"string\", default: \"\", optional: true },\n Tags: { type: \"string\", default: \"\", optional: true },\n PreviewTime: { type: \"int\", default: 0 },\n AudioFile: { type: \"string\", default: \"\", optional: true },\n BackgroundFile: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { Beatmap } from \"./beatmap.js\";\nimport { RealmNamedFileUsage } from \"./realmNamedFileUsage.js\";\n\nexport class BeatmapSet extends Realm.Object<BeatmapSet> {\n ID!: string;\n OnlineID!: number;\n DateAdded!: Date;\n DateSubmitted?: Date;\n DateRanked?: Date;\n Beatmaps!: Array<Beatmap>;\n Files!: Array<RealmNamedFileUsage>;\n Status!: number;\n DeletePending!: boolean;\n Hash?: string;\n Protected!: boolean;\n\n static schema: ObjectSchema = {\n name: \"BeatmapSet\",\n primaryKey: \"ID\",\n properties: {\n ID: { type: \"uuid\", default: \"\" },\n OnlineID: { type: \"int\", default: -1 },\n DateAdded: { type: \"date\" },\n DateSubmitted: { type: \"date\", optional: true },\n DateRanked: { type: \"date\", optional: true },\n Beatmaps: { type: \"list\", objectType: \"Beatmap\", default: [] },\n Files: { type: \"list\", objectType: \"RealmNamedFileUsage\", default: [] },\n Status: { type: \"int\", default: -3 },\n DeletePending: { type: \"bool\", default: false },\n Hash: { type: \"string\", default: \"\", optional: true },\n Protected: { type: \"bool\", default: false },\n },\n };\n}\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmFile extends Realm.Object<RealmFile> {\n Hash?: string;\n\n static schema: ObjectSchema = {\n name: \"File\",\n primaryKey: \"Hash\",\n properties: {\n Hash: { type: \"string\", default: \"\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\n\nexport class RealmUser extends Realm.Object<RealmUser> {\n OnlineID!: number;\n Username?: string;\n CountryCode?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmUser\",\n embedded: true,\n properties: {\n OnlineID: { type: \"int\", default: 1 },\n Username: { type: \"string\", default: \"\", optional: true },\n CountryCode: { type: \"string\", optional: true },\n },\n };\n}\n\n","import Realm from \"realm\";\nimport type { ObjectSchema } from \"realm\";\nimport { RealmFile } from \"./realmFile.js\";\n\nexport class RealmNamedFileUsage extends Realm.Object<RealmNamedFileUsage> {\n File!: RealmFile;\n Filename?: string;\n\n static embedded = true;\n\n static schema: ObjectSchema = {\n name: \"RealmNamedFileUsage\",\n embedded: true,\n properties: {\n File: \"File\",\n Filename: { type: \"string\", optional: true },\n },\n };\n}\n"],"mappings":"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","names":["mod_exports","Realm","path","Realm","Realm","Realm","Realm","Realm","Realm","path"]}
|
package/package.json
CHANGED
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "osu-play",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "Play OSU!Lazer beatmaps from the terminal.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "bin/osu-play.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"bin",
|
|
9
|
+
"dist",
|
|
10
|
+
"package.json",
|
|
11
|
+
"README.md",
|
|
12
|
+
"tsconfig.json",
|
|
13
|
+
"LICENSE"
|
|
14
|
+
],
|
|
15
|
+
"types": "dist/index.d.ts",
|
|
7
16
|
"bin": {
|
|
8
17
|
"osu-play": "./bin/osu-play.js"
|
|
9
18
|
},
|
|
10
19
|
"scripts": {
|
|
11
20
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
12
|
-
"
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"start": "./bin/osu-play.js",
|
|
23
|
+
"dev:start": "tsc && ./bin/osu-play.js",
|
|
13
24
|
"clean": "rm -rf dist"
|
|
14
25
|
},
|
|
15
26
|
"author": "KorigamiK",
|
|
16
27
|
"license": "MIT",
|
|
17
28
|
"devDependencies": {
|
|
18
|
-
"
|
|
29
|
+
"@types/node": "^20.8.9",
|
|
19
30
|
"@types/prompts": "^2.4.7",
|
|
20
|
-
"
|
|
31
|
+
"tsup": "^7.2.0",
|
|
32
|
+
"typescript": "^5.2.2"
|
|
21
33
|
},
|
|
22
34
|
"dependencies": {
|
|
23
35
|
"prompts": "^2.4.2",
|
package/tsconfig.json
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
{
|
|
2
|
+
"exclude": [
|
|
3
|
+
"node_modules"
|
|
4
|
+
],
|
|
5
|
+
"include": [
|
|
6
|
+
"./src/**/*"
|
|
7
|
+
],
|
|
2
8
|
"compilerOptions": {
|
|
3
9
|
/* Visit https://aka.ms/tsconfig to read more about this file */
|
|
4
10
|
/* Projects */
|
|
@@ -100,6 +106,4 @@
|
|
|
100
106
|
/* Completeness */
|
|
101
107
|
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
|
102
108
|
},
|
|
103
|
-
|
|
104
|
-
"include": ["./src/**/*"]
|
|
105
|
-
}
|
|
109
|
+
}
|
package/src/main.ts
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import { existsSync } from "node:fs";
|
|
3
|
-
import { execSync } from "node:child_process";
|
|
4
|
-
|
|
5
|
-
import Realm from "realm";
|
|
6
|
-
import prompts from "prompts";
|
|
7
|
-
import { BeatmapSet } from "./realm/schema/mod.js";
|
|
8
|
-
import { getConfigDir, getRealmDBPath } from "./utils/mod.js";
|
|
9
|
-
import { getLazerDB, getNamedFileHash, hashedFilePath } from "./realm/mod.js";
|
|
10
|
-
|
|
11
|
-
export default async function main() {
|
|
12
|
-
console.log("[INFO] OSU!list");
|
|
13
|
-
|
|
14
|
-
const realmDBPath = getRealmDBPath(
|
|
15
|
-
path.join(getConfigDir() || ".", "osu-play"),
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
if (realmDBPath == null) {
|
|
19
|
-
console.log("[ERROR] Realm DB not found");
|
|
20
|
-
process.exit(1);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
const currentSchema = Realm.schemaVersion(realmDBPath);
|
|
24
|
-
console.log(`currentSchema: ${currentSchema}`);
|
|
25
|
-
|
|
26
|
-
Realm.flags.ALLOW_CLEAR_TEST_STATE = true;
|
|
27
|
-
|
|
28
|
-
const realm: Realm = await getLazerDB(realmDBPath);
|
|
29
|
-
|
|
30
|
-
console.log(`realm.isClosed: ${realm.isClosed}`);
|
|
31
|
-
|
|
32
|
-
const beatmapSets = realm.objects(BeatmapSet);
|
|
33
|
-
|
|
34
|
-
console.log(`beatmaps: ${beatmapSets.length}`);
|
|
35
|
-
|
|
36
|
-
// Get the map index from the user
|
|
37
|
-
const selectedBeatmapSet = (
|
|
38
|
-
await prompts({
|
|
39
|
-
type: "autocomplete",
|
|
40
|
-
name: "beatmapSet",
|
|
41
|
-
message: "Which map do you want to play:",
|
|
42
|
-
choices: beatmapSets.map((beatmapSet) => {
|
|
43
|
-
const meta = beatmapSet.Beatmaps[0].Metadata;
|
|
44
|
-
return {
|
|
45
|
-
title: `${meta.Title} : ${meta.Artist} - ${meta.TitleUnicode} : ${meta.ArtistUnicode}`,
|
|
46
|
-
value: beatmapSet,
|
|
47
|
-
};
|
|
48
|
-
}),
|
|
49
|
-
})
|
|
50
|
-
).beatmapSet;
|
|
51
|
-
|
|
52
|
-
console.log(`Map : ${selectedBeatmapSet.Beatmaps[0].Metadata.Title}`);
|
|
53
|
-
const fileName = selectedBeatmapSet.Beatmaps[0].Metadata.AudioFile;
|
|
54
|
-
const fileHash = fileName
|
|
55
|
-
? getNamedFileHash(fileName, selectedBeatmapSet)
|
|
56
|
-
: undefined;
|
|
57
|
-
const filePath = fileHash ? hashedFilePath(fileHash) : undefined;
|
|
58
|
-
if (filePath && existsSync(filePath)) {
|
|
59
|
-
console.log(`File exists: ${filePath}`);
|
|
60
|
-
} else {
|
|
61
|
-
console.log(`File does not exist: ${filePath}`);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Open file using exo-open.
|
|
65
|
-
console.log(`Playing file ${selectedBeatmapSet.Beatmaps[0].Metadata.Title}`);
|
|
66
|
-
filePath && execSync(`exo-open ${filePath}`);
|
|
67
|
-
|
|
68
|
-
realm.close();
|
|
69
|
-
console.log(`realm.isClosed: ${realm.isClosed}`);
|
|
70
|
-
|
|
71
|
-
// Realm.clearTestState();
|
|
72
|
-
}
|
package/src/realm/mod.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import Realm from "realm";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { getDataDir } from "../utils/mod.js";
|
|
4
|
-
import {
|
|
5
|
-
Beatmap,
|
|
6
|
-
BeatmapMetadata,
|
|
7
|
-
BeatmapSet,
|
|
8
|
-
RealmFile,
|
|
9
|
-
RealmNamedFileUsage,
|
|
10
|
-
RealmUser,
|
|
11
|
-
} from "./schema/mod.js";
|
|
12
|
-
|
|
13
|
-
export const getLazerDB = async (realmDBPath: string) => {
|
|
14
|
-
const realm = await Realm.open({
|
|
15
|
-
schema: [
|
|
16
|
-
BeatmapSet,
|
|
17
|
-
RealmFile,
|
|
18
|
-
RealmNamedFileUsage,
|
|
19
|
-
Beatmap,
|
|
20
|
-
BeatmapMetadata,
|
|
21
|
-
RealmUser,
|
|
22
|
-
],
|
|
23
|
-
path: realmDBPath,
|
|
24
|
-
schemaVersion: 36,
|
|
25
|
-
onMigration: (oldRealm, newRealm) => {
|
|
26
|
-
console.log(
|
|
27
|
-
`[onMigration]: Migrating ${oldRealm.path} - ${oldRealm.schemaVersion} -> ${newRealm.path} - ${newRealm.schemaVersion}`,
|
|
28
|
-
);
|
|
29
|
-
},
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
return realm;
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
export const hashedFilePath = (hash: string) => {
|
|
36
|
-
const dataDir = getDataDir();
|
|
37
|
-
if (!dataDir) return null;
|
|
38
|
-
return path.join(
|
|
39
|
-
dataDir,
|
|
40
|
-
"osu",
|
|
41
|
-
"files",
|
|
42
|
-
hash.slice(0, 1),
|
|
43
|
-
hash.slice(0, 2),
|
|
44
|
-
hash,
|
|
45
|
-
);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const getNamedFileHash = (fileName: string, beatmapSet: BeatmapSet) => {
|
|
49
|
-
const files = beatmapSet.Files;
|
|
50
|
-
for (const file of files) {
|
|
51
|
-
if (file.Filename == fileName) return file.File.Hash;
|
|
52
|
-
}
|
|
53
|
-
return undefined;
|
|
54
|
-
};
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import Realm from "realm";
|
|
2
|
-
import type { ObjectSchema } from "realm";
|
|
3
|
-
import { BeatmapMetadata } from "./beatmapMetadata.js";
|
|
4
|
-
|
|
5
|
-
export class Beatmap extends Realm.Object<Beatmap> {
|
|
6
|
-
ID!: string;
|
|
7
|
-
DifficultyName?: string;
|
|
8
|
-
Ruleset!: any;
|
|
9
|
-
Difficulty!: any;
|
|
10
|
-
Metadata!: BeatmapMetadata;
|
|
11
|
-
UserSettings!: any;
|
|
12
|
-
BeatmapSet!: any;
|
|
13
|
-
Status!: number;
|
|
14
|
-
OnlineID!: number;
|
|
15
|
-
Length!: number;
|
|
16
|
-
BPM!: number;
|
|
17
|
-
Hash?: string;
|
|
18
|
-
StarRating!: number;
|
|
19
|
-
MD5Hash?: string;
|
|
20
|
-
OnlineMD5Hash?: string;
|
|
21
|
-
LastLocalUpdate?: Date;
|
|
22
|
-
LastOnlineUpdate?: Date;
|
|
23
|
-
Hidden!: boolean;
|
|
24
|
-
AudioLeadIn!: number;
|
|
25
|
-
StackLeniency!: number;
|
|
26
|
-
SpecialStyle!: boolean;
|
|
27
|
-
LetterboxInBreaks!: boolean;
|
|
28
|
-
WidescreenStoryboard!: boolean;
|
|
29
|
-
EpilepsyWarning!: boolean;
|
|
30
|
-
SamplesMatchPlaybackRate!: boolean;
|
|
31
|
-
LastPlayed?: Date;
|
|
32
|
-
DistanceSpacing!: number;
|
|
33
|
-
BeatDivisor!: number;
|
|
34
|
-
GridSize!: number;
|
|
35
|
-
TimelineZoom!: number;
|
|
36
|
-
EditorTimestamp?: number;
|
|
37
|
-
CountdownOffset!: number;
|
|
38
|
-
|
|
39
|
-
static schema: ObjectSchema = {
|
|
40
|
-
name: "Beatmap",
|
|
41
|
-
primaryKey: "ID",
|
|
42
|
-
properties: {
|
|
43
|
-
ID: { type: "uuid", default: "" },
|
|
44
|
-
DifficultyName: { type: "string", default: "", optional: true },
|
|
45
|
-
// Ruleset: { type: "object", objectType: "Ruleset", default: null },
|
|
46
|
-
// Difficulty: { type: "object", objectType: "BeatmapDifficulty", default: null },
|
|
47
|
-
Metadata: {
|
|
48
|
-
type: "object",
|
|
49
|
-
objectType: "BeatmapMetadata",
|
|
50
|
-
default: null,
|
|
51
|
-
},
|
|
52
|
-
// UserSettings: { type: "object", objectType: "BeatmapUserSettings", default: null },
|
|
53
|
-
BeatmapSet: { type: "object", objectType: "BeatmapSet", default: null },
|
|
54
|
-
Status: { type: "int", default: -3 },
|
|
55
|
-
OnlineID: { type: "int", default: -1 },
|
|
56
|
-
Length: { type: "double", default: 0 },
|
|
57
|
-
BPM: { type: "double", default: 0 },
|
|
58
|
-
Hash: { type: "string", default: "", optional: true },
|
|
59
|
-
StarRating: { type: "double", default: -1 },
|
|
60
|
-
MD5Hash: { type: "string", default: "", optional: true },
|
|
61
|
-
OnlineMD5Hash: {
|
|
62
|
-
type: "string",
|
|
63
|
-
default: "",
|
|
64
|
-
optional: true,
|
|
65
|
-
},
|
|
66
|
-
LastLocalUpdate: { type: "date", optional: true },
|
|
67
|
-
LastOnlineUpdate: { type: "date", optional: true },
|
|
68
|
-
Hidden: { type: "bool", default: false },
|
|
69
|
-
AudioLeadIn: { type: "double", default: 0 },
|
|
70
|
-
StackLeniency: { type: "float", default: 0.7 },
|
|
71
|
-
SpecialStyle: { type: "bool", default: false },
|
|
72
|
-
LetterboxInBreaks: { type: "bool", default: false },
|
|
73
|
-
WidescreenStoryboard: { type: "bool", default: false },
|
|
74
|
-
EpilepsyWarning: { type: "bool", default: false },
|
|
75
|
-
SamplesMatchPlaybackRate: { type: "bool", default: false },
|
|
76
|
-
LastPlayed: { type: "date", optional: true },
|
|
77
|
-
DistanceSpacing: { type: "double", default: 0 },
|
|
78
|
-
BeatDivisor: { type: "int", default: 0 },
|
|
79
|
-
GridSize: { type: "int", default: 0 },
|
|
80
|
-
TimelineZoom: { type: "double", default: 0 },
|
|
81
|
-
EditorTimestamp: { type: "double", optional: true },
|
|
82
|
-
CountdownOffset: { type: "int", default: 0 },
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import Realm from "realm";
|
|
2
|
-
import type { ObjectSchema } from "realm";
|
|
3
|
-
import { RealmUser } from "./realmUser.js";
|
|
4
|
-
|
|
5
|
-
export class BeatmapMetadata extends Realm.Object<BeatmapMetadata> {
|
|
6
|
-
Title?: string;
|
|
7
|
-
TitleUnicode?: string;
|
|
8
|
-
Artist?: string;
|
|
9
|
-
ArtistUnicode?: string;
|
|
10
|
-
Author?: RealmUser;
|
|
11
|
-
Source?: string;
|
|
12
|
-
Tags?: string;
|
|
13
|
-
PreviewTime?: number;
|
|
14
|
-
AudioFile?: string;
|
|
15
|
-
BackgroundFile?: string;
|
|
16
|
-
|
|
17
|
-
static schema: ObjectSchema = {
|
|
18
|
-
name: "BeatmapMetadata",
|
|
19
|
-
properties: {
|
|
20
|
-
Title: { type: "string", default: "", optional: true },
|
|
21
|
-
TitleUnicode: { type: "string", default: "", optional: true },
|
|
22
|
-
Artist: { type: "string", default: "", optional: true },
|
|
23
|
-
ArtistUnicode: { type: "string", default: "", optional: true },
|
|
24
|
-
Author: { type: "object", objectType: "RealmUser", default: null },
|
|
25
|
-
Source: { type: "string", default: "", optional: true },
|
|
26
|
-
Tags: { type: "string", default: "", optional: true },
|
|
27
|
-
PreviewTime: { type: "int", default: 0 },
|
|
28
|
-
AudioFile: { type: "string", default: "", optional: true },
|
|
29
|
-
BackgroundFile: { type: "string", default: "", optional: true },
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|