diff --git a/.vscode/settings.json b/.vscode/settings.json index 004d237..ab64178 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,7 @@ "prettier.trailingComma": "none", "prettier.semi": false, "prettier.quoteProps": "preserve", - "prettier.printWidth": 500 + "prettier.printWidth": 500, + "vscord.status.details.enabled": true, + "vscord.app.privacyMode.enable": false } diff --git a/README.md b/README.md index cacc4ca..9b91bd5 100644 --- a/README.md +++ b/README.md @@ -34,15 +34,15 @@ Git 2.40.0+ is required. ## Config -- encoder: can be "nvidia" (NVENC), "intel" (QSV) or "cpu" (libx264). -- motionBlurCapable: set this to true to get renders with motion blur. -- usingOsuApi: set this to true to get renders that need a scoreboard and that therefore needs to fetch data from the osu! api (leaderboard). Set an osu! api key in osuApiKey to use this. -- debugLogs: print more logs when disconnected from the o!rdr server. -- deleteRenderedVideos: automatically delete rendered videos from your drive once they have been successfully sent to the o!rdr server. -- renderOnInactivityOnly: connect to the o!rdr server once the computer is idle (check every 60 seconds if mouse or keyboard hasn't been touched for 30 seconds). To use this, you need to install the desktop-idle package with "npm install --save desktop-idle". On Windows, it needs Python and VS > 2016 to compile what it needs to work correctly. Check [this](https://github.com/bithavoc/node-desktop-idle) for more informations about this package. Won't work on precompiled builds for the moment. -- customSongsFolderPath: use a custom path to store songs downloaded instead of the default (files/danser/Songs). Can be useful if you want new maps on osu! for example. -- logTimestamps: add a timestamp before every log line. -- customization: (to use with the official o!rdr instance only) with textColor and backgroundType - change the way your renderer name looks on the website! Changes made to this field are hotswappable and changes are effective almost instantly. +- `encoder`: can be "nvidia" (NVENC), "intel" (QSV) or "cpu" (libx264). +- `motionBlurCapable`: set this to true to get renders with motion blur. +- `osuOauthClientId` and `osuOauthClientSecret`: fill these fields with your osu! OAuth credentials to get renders that need a scoreboard and that therefore needs to fetch data from the osu! API (v2). +- `debugLogs`: print more logs when disconnected from the o!rdr server. +- `deleteRenderedVideos`: automatically delete rendered videos from your drive once they have been successfully sent to the o!rdr server. +- `renderOnInactivityOnly`: connect to the o!rdr server once the computer is idle (check every 60 seconds if mouse or keyboard hasn't been touched for 30 seconds). To use this, you need to install the desktop-idle package with "npm install --save desktop-idle". On Windows, it needs Python and VS > 2016 to compile what it needs to work correctly. Check [this](https://github.com/bithavoc/node-desktop-idle) for more informations about this package. Won't work on precompiled builds for the moment. +- `customSongsFolderPath`: use a custom path to store songs downloaded instead of the default (files/danser/Songs). Can be useful if you want new maps on osu! for example. +- `logTimestamps`: add a timestamp before every log line. +- `customization`: (to use with the official o!rdr instance only) with `textColor` and `backgroundType` - change the way your renderer name looks on the website! Changes made to this field are hotswappable and changes are effective almost instantly. Available options for textColor: `salmon`, `azure`, `emerald`, `pear`, `pumpkin`, `red`, `teal-blue`, `cream`, `silver-coin`, `botany`, `calm-gold`, `limestone`, `alpine-morning-blue`, `transluscent-white`, `yellow-orange`, `algae-green`. Empty string for default white. diff --git a/files/danserHandler.js b/files/danserHandler.js index a886c4b..85e35a7 100644 --- a/files/danserHandler.js +++ b/files/danserHandler.js @@ -2,7 +2,7 @@ const uploadVideo = require("./uploadVideo") var spawn = require("child_process").spawn const { updatePresence } = require("./presence") const fs = require("fs") -const { readConfig } = require("./util") +const { readConfig, exit } = require("./util") let isRendering = false, danserProcess @@ -41,7 +41,7 @@ exports.startDanser = async (danserArguments, videoName) => { danserProcess = spawn("./danser", danserArguments, { cwd: "files/danser" }) const { sendProgression, handlePanic } = require("./server") danserProcess.stdout.setEncoding("utf8") - danserProcess.stdout.on(`data`, data => { + danserProcess.stdout.on(`data`, async data => { if (data.includes("Progress") && canGetProgress) { if (!config.showFullDanserLogs) { console.log(data) @@ -80,6 +80,15 @@ exports.startDanser = async (danserArguments, videoName) => { if (isPanicking) { panicLogs += data } + if (data.includes("Error connecting to osu!api")) { + clearInterval(stuckCheckInterval) + await this.abortRender() + isRendering = false + sendProgression("bad_osu_oauth") + if (config.discordPresence) updatePresence("Idle", false) + console.log("It looks like your osu! OAuth keys are invalid! Please fix them before running the client.") + await exit() + } }) danserProcess.stderr.setEncoding("utf8") danserProcess.stderr.on("data", data => { diff --git a/files/server.js b/files/server.js index 86d13ba..d38c97c 100644 --- a/files/server.js +++ b/files/server.js @@ -48,7 +48,7 @@ exports.startServer = async () => { ioClient.on("connect", () => { console.log("Connected to the o!rdr server!") - ioClient.emit("id", { id: config.id, version: version, usingOsuApi: config.usingOsuApi, motionBlurCapable: config.motionBlurCapable, uhdCapable: config.uhdCapable, isRendering: isRendering(), encodingWith: config.encoder, customization: customization }) + ioClient.emit("id", { id: config.id, version: version, usingOsuApi: config.osuOauthClientId !== "" && config.osuOauthClientSecret !== "", motionBlurCapable: config.motionBlurCapable, uhdCapable: config.uhdCapable, isRendering: isRendering(), encodingWith: config.encoder, customization: customization }) }) ioClient.on("disconnect", () => { @@ -57,9 +57,7 @@ exports.startServer = async () => { ioClient.on("data", data => { if (!fs.existsSync("./files/danser/settings/default.json")) { - console.log( - `danser's settings file is missing! It's probably because you made a "clean" installation of the client without having recreated the Songs/Skins folders or having danser regenerate its settings file. You should run the benchmark (achievable without having the client's config.json file containing your ID), don't let the client send an application request, just CTRL+C when the benchmark finished. Then, replace the new config.json by the new one with your ID in it.` - ) + console.log(`danser's settings file is missing! It's probably because you made a "clean" installation of the client without having recreated the Songs/Skins folders or having danser regenerate its settings file. You should run the benchmark (achievable without having the client's config.json file containing your ID), don't let the client send an application request, just CTRL+C when the benchmark finished. Then, replace the new config.json by the new one with your ID in it.`) } dataProcessor(data) }) diff --git a/files/settingsGenerator.js b/files/settingsGenerator.js index ca917c7..32d0ec5 100644 --- a/files/settingsGenerator.js +++ b/files/settingsGenerator.js @@ -10,10 +10,11 @@ module.exports = async (type, resolution, turbo, cb) => { if (!fs.existsSync("files/danser/rawReplays")) fs.mkdirSync("files/danser/rawReplays") if (!fs.existsSync("files/danser/videos")) fs.mkdirSync("files/danser/videos") } else if (type === "change") { - if (config.usingOsuApi) { + if (config.osuOauthClientId !== "" && config.osuOauthClientSecret !== "") { const danserCredentials = require(process.cwd() + "/files/danser/settings/credentials.json") - if (danserCredentials.ApiV1Key !== config.osuApiKey) { - danserCredentials.ApiV1Key = config.osuApiKey + if (danserCredentials.ClientId !== config.osuOauthClientId || danserCredentials.ClientSecret !== config.osuOauthClientSecret) { + danserCredentials.ClientId = config.osuOauthClientId + danserCredentials.ClientSecret = config.osuOauthClientSecret fs.writeFileSync("files/danser/settings/credentials.json", JSON.stringify(danserCredentials, null, 1), "utf-8", err => { if (err) throw err }) diff --git a/files/util.js b/files/util.js index a3058c9..a269b9c 100644 --- a/files/util.js +++ b/files/util.js @@ -58,8 +58,8 @@ exports.asyncExtract = async (input, output, filename, type) => { let emptyConfig = { id: "", encoder: "", - usingOsuApi: false, - osuApiKey: "", + osuOauthClientId: "", + osuOauthClientSecret: "", motionBlurCapable: false, uhdCapable: false, debugLogs: false, @@ -99,3 +99,17 @@ exports.writeConfig = async (key, value) => { fs.writeFileSync(process.cwd() + "/config.json", JSON.stringify(config, null, 2), { encoding: "utf-8" }) return config } + +exports.updateConfig = async () => { + let currentConfig = await this.readConfig() + if (typeof currentConfig.usingOsuApi !== "undefined") { + if (currentConfig.osuApiKey !== "") console.log("You were using an osu! API v1 key with the o!rdr client.") + console.log("danser now uses the osu! API v2 to retrieve leaderboards, so you'll need to use an OAuth key that you can get on the osu! website: https://osu.ppy.sh/home/account/edit (OAuth section) if you want your client to be able to render videos requiring a scoreboard.") + console.log('The "Application Callback URLs" field can be left empty, but if you want your client config to be future-proof you should enter this: http://localhost:8294') + delete currentConfig.usingOsuApi + delete currentConfig.osuApiKey + currentConfig.osuOauthClientId = "" + currentConfig.osuOauthClientSecret = "" + fs.writeFileSync(process.cwd() + "/config.json", JSON.stringify(currentConfig, null, 2), { encoding: "utf-8" }) + } +} diff --git a/main.js b/main.js index d2d3314..6c49a32 100644 --- a/main.js +++ b/main.js @@ -1,13 +1,15 @@ -const { readConfig, exit } = require("./files/util") +const { readConfig, updateConfig, exit } = require("./files/util") const checkDanserVersion = require("./files/checkDanserVersion") const axios = require("axios") const fs = require("fs") -const version = 24 +const version = 25 module.exports = { version } const { startServer } = require("./files/server") const firstLaunch = require("./files/firstLaunch") async function main() { + await updateConfig() + let config = await readConfig() if (config.logTimestamps) { @@ -27,10 +29,10 @@ async function main() { clientData = clientData.data } else { // if we're using a custom server, we set the version that the server should have sent us to the current version to bypass the check - clientData = { clientVersion: version } + clientData = { minimumClientVersion: version, maximumClientVersion: version } } - if (version != clientData.clientVersion) { + if (version < clientData.minimumClientVersion || version > clientData.maximumClientVersion) { const clientUpdater = require("./files/clientUpdater") console.log("Client version seems incorrect or out of date. Running updater.") clientUpdater()