Skip to content

Commit

Permalink
Add support for danser 0.10.0
Browse files Browse the repository at this point in the history
- Use osu! OAuth for API v2 instead of API v1 (danser requirement)
- Detect when the supplied OAuth keys are invalid
- Check for minimum and maximum client version allowed by the o!rdr server
- Bump version
  • Loading branch information
MasterIO02 committed Nov 3, 2024
1 parent 20688f6 commit d4635f7
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 25 deletions.
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down
13 changes: 11 additions & 2 deletions files/danserHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 => {
Expand Down
6 changes: 2 additions & 4 deletions files/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -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", () => {
Expand All @@ -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)
})
Expand Down
7 changes: 4 additions & 3 deletions files/settingsGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
Expand Down
18 changes: 16 additions & 2 deletions files/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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" })
}
}
10 changes: 6 additions & 4 deletions main.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand All @@ -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()
Expand Down

0 comments on commit d4635f7

Please sign in to comment.