diff --git a/.env.example b/example.env similarity index 92% rename from .env.example rename to example.env index a1bb39f..b757a14 100644 --- a/.env.example +++ b/example.env @@ -1,10 +1,10 @@ RCCSERVICE= ARBITER_TOKEN= +ARBITER_PASSWORD= BASE_URL=https://sitetest.unexp.xyz RENDER_FORMAT=PNG -RENDER_BASE64= RENDER_USER_WIDTH=720 RENDER_USER_HEIGHT=720 diff --git a/src/index.js b/src/index.js index 809a1f8..f7927c7 100644 --- a/src/index.js +++ b/src/index.js @@ -1,40 +1,37 @@ -require("dotenv").config() -const express = require("express") -const app = express() +require("dotenv").config(); +const express = require("express"); +const app = express(); -const logger = require("./lib/logger.js") +const logger = require("./lib/logger.js"); -if (process.platform == "linux") logger.warn("Game hosting might not be fully compatible with Linux") +if (process.platform == "linux") logger.warn("Game hosting might not be fully compatible with Linux"); -global.games = new Map() +global.games = new Map(); setInterval(() => { global.games.forEach(async (value, key) => { - if (!(await value.Running())) value.Stop() - }) -}, 15000) + if (!(await value.Running())) value.Stop(); + }); +}, 15000); -app.use("/game/start", require("./routes/game/start.js")) -app.use("/game/stop", require("./routes/game/stop.js")) -app.use("/game/running", require("./routes/game/running.js")) -app.use("/game/renew", require("./routes/game/renew.js")) -app.use("/game/status", require("./routes/game/status.js")) -app.use("/game/execute", require("./routes/game/execute.js")) +app.use("/game/start", require("./routes/game/start.js")); +app.use("/game/stop", require("./routes/game/stop.js")); +app.use("/game/running", require("./routes/game/running.js")); +app.use("/game/renew", require("./routes/game/renew.js")); +app.use("/game/status", require("./routes/game/status.js")); +app.use("/game/execute", require("./routes/game/execute.js")); -app.use("/render/asset", require("./routes/render/asset.js")) -app.use("/render/game", require("./routes/render/game.js")) -app.use("/render/headshot", require("./routes/render/headshot.js")) -app.use("/render/bodyshot", require("./routes/render/bodyshot.js")) +app.use("/render/asset", require("./routes/render/asset.js")); +//app.use("/render/game", require("./routes/render/game.js")) +//app.use("/render/texture", require("./routes/render/texture.js")) +app.use("/render/user", require("./routes/render/user.js")); -app.use("/render/3d/asset", require("./routes/render/3d/asset.js")) -app.use("/render/3d/user", require("./routes/render/3d/user.js")) - -app.use("*", require("./routes/index.js")) +app.use("*", require("./routes/index.js")); app.listen(process.env.PORT || 64989, () => { - logger.boot(`Listening on http://127.0.0.1:${process.env.PORT || 64989}/`) -}) + logger.boot(`Listening on http://127.0.0.1:${process.env.PORT || 64989}/`); +}); process.on("uncaughtException", (err) => { - logger.error(err.message) -}) + logger.error(err.message); +}); diff --git a/src/lib/classes/RCCService.js b/src/lib/classes/RCCService.js index b96e29d..732dbd2 100644 --- a/src/lib/classes/RCCService.js +++ b/src/lib/classes/RCCService.js @@ -5,6 +5,8 @@ const waitPort = require("wait-port") const logger = require("../../lib/logger.js") const randport = require("../../lib/randport.js") +const chalk = require("chalk") + class RCCService extends EventEmitter { constructor() { super() @@ -16,16 +18,17 @@ class RCCService extends EventEmitter { this.port = await randport.tcp() if (process.platform == "win32") { - this.proc = child_process.spawn("RCCService.exe", ["-Console", "-PlaceId:-1", `-Port`, this.port], { cwd: process.env.RCCSERVICE }) + this.proc = child_process.spawn("RCCService.exe", ["-Console", "-PlaceId:-1", `-Port`, this.port], { cwd: process.env.RCCSERVICE, stdio: "inherit" }) } else { - this.proc = child_process.spawn("wine", ["RCCService.exe", "-Console", "-PlaceId:-1", `-Port`, this.port], { cwd: process.env.RCCSERVICE }) + this.proc = child_process.spawn("wine", ["RCCService.exe", "-Console", "-PlaceId:-1", `-Port`, this.port], { cwd: process.env.RCCSERVICE, stdio: "inherit" }) } this.proc.once("spawn", async () => { - logger.info(`[${this.port}] RCCService instance spawned`) + logger.info(`${chalk.gray(`[${this.port}]`)} RCCService instance spawned`) const { open } = await waitPort({ host: "127.0.0.1", port: this.port, timeout: 5000, output: "silent" }).catch((e) => console.log(e)) if (!open || this.proc.exitCode !== null) { - logger.error(`[${this.port}] RCCService could not listen`) + this.proc.kill() + logger.error(`${chalk.gray(`[${this.port}]`)} RCCService could not listen`) return resolve(false) } @@ -33,8 +36,8 @@ class RCCService extends EventEmitter { }) this.proc.once("exit", () => { - this.proc = null - logger.info(`[${this.port}] RCCService instance exited`) + this.proc.kill() + logger.info(`${chalk.gray(`[${this.port}]`)} RCCService instance exited`) }) } catch (_) { resolve(false) diff --git a/src/lib/classes/RenderJob.js b/src/lib/classes/RenderJob.js index 8a0d840..2bdc29d 100644 --- a/src/lib/classes/RenderJob.js +++ b/src/lib/classes/RenderJob.js @@ -1,19 +1,19 @@ -const { readFile } = require("fs/promises") +const { readFile } = require("fs/promises"); -const Job = require("./Job.js") -const logger = require("../logger.js") +const Job = require("./Job.js"); +const logger = require("../logger.js"); class RenderJob extends Job { constructor() { - super() + super(); } - async RenderHeadshot(id, base64 = false) { - const started = await this.Start() - if (!started) throw new Error("RCCService failed to start") - if (!this.client) await this.CreateClient() + async RenderHeadshot(id) { + const started = await this.Start(); + if (!started) throw new Error("RCCService failed to start"); + if (!this.client) await this.CreateClient(); - logger.info(`[${this.id}] Headshot RenderJob started for ${id}`) + logger.info(`[${this.id}] Headshot RenderJob started for ${id}`); const result = await this.OpenJobEx({ name: this.id, @@ -32,24 +32,21 @@ class RenderJob extends Job { { type: "LUA_TNUMBER", value: id }, ], }, - }).catch((e) => false) + }).catch((e) => false); - logger.info(`[${this.id}] Headshot RenderJob finished for ${id}`) + logger.info(`[${this.id}] Headshot RenderJob finished for ${id}`); - await this.Stop() - - if (!result) return false - if (base64) return result[0].OpenJobExResult.LuaValue[0].value - return Buffer.from(result[0]?.OpenJobExResult?.LuaValue[0]?.value, "base64") + if (!result) return false; + return result[0]?.OpenJobExResult?.LuaValue[0]?.value; } - async RenderBodyshot(id, base64 = false, three_d = false) { - const started = await this.Start() - if (!started) throw new Error("RCCService failed to start") - if (!this.client) await this.CreateClient() + async RenderBodyshot(id, three_d = false) { + const started = await this.Start(); + if (!started) throw new Error("RCCService failed to start"); + if (!this.client) await this.CreateClient(); - if (three_d) logger.info(`[${this.id}] 3D Bodyshot RenderJob started for ${id}`) - else logger.info(`[${this.id}] Bodyshot RenderJob started for ${id}`) + if (three_d) logger.info(`[${this.id}] 3D Bodyshot RenderJob started for ${id}`); + else logger.info(`[${this.id}] Bodyshot RenderJob started for ${id}`); const result = await this.OpenJobEx({ name: this.id, @@ -68,25 +65,22 @@ class RenderJob extends Job { { type: "LUA_TNUMBER", value: id }, ], }, - }).catch((e) => false) + }).catch((e) => false); - if (three_d) logger.info(`[${this.id}] 3D Bodyshot RenderJob finished for ${id}`) - else logger.info(`[${this.id}] Bodyshot RenderJob finished for ${id}`) + if (three_d) logger.info(`[${this.id}] 3D Bodyshot RenderJob finished for ${id}`); + else logger.info(`[${this.id}] Bodyshot RenderJob finished for ${id}`); - await this.Stop() - - if (!result) return false - if (base64 || three_d) return result[0].OpenJobExResult.LuaValue[0].value - return Buffer.from(result[0]?.OpenJobExResult?.LuaValue[0]?.value, "base64") + if (!result) return false; + return result[0]?.OpenJobExResult?.LuaValue[0]?.value; } - async RenderAsset(id, base64 = false, three_d = false) { - const started = await this.Start() - if (!started) throw new Error("RCCService failed to start") - if (!this.client) await this.CreateClient() + async RenderAsset(id, three_d = false) { + const started = await this.Start(); + if (!started) throw new Error("RCCService failed to start"); + if (!this.client) await this.CreateClient(); - if (three_d) logger.info(`[${this.id}] 3D Asset RenderJob started for ${id}`) - else logger.info(`[${this.id}] Asset RenderJob started for ${id}`) + if (three_d) logger.info(`[${this.id}] 3D Asset RenderJob started for ${id}`); + else logger.info(`[${this.id}] Asset RenderJob started for ${id}`); const result = await this.OpenJobEx({ name: this.id, @@ -106,29 +100,26 @@ class RenderJob extends Job { { type: "LUA_TBOOLEAN", value: "true" }, ], }, - }).catch((e) => false) + }).catch((e) => false); - if (three_d) logger.info(`[${this.id}] 3D Asset RenderJob finished for ${id}`) - else logger.info(`[${this.id}] Asset RenderJob finished for ${id}`) + if (three_d) logger.info(`[${this.id}] 3D Asset RenderJob finished for ${id}`); + else logger.info(`[${this.id}] Asset RenderJob finished for ${id}`); - await this.Stop() - - if (!result) return false - if (base64 || three_d) return result[0].OpenJobExResult.LuaValue[0].value - return Buffer.from(result[0]?.OpenJobExResult?.LuaValue[0]?.value, "base64") + if (!result) return false; + return result[0]?.OpenJobExResult?.LuaValue[0]?.value; } - async RenderPlace(id, base64 = false) { - const response = await axios(`${process.env.BASE_URL}/API/Game/${id}?t=${process.env.ARBITER_TOKEN}`).catch((_) => reject(_)) - const { server_token, server_port, server_owner_id } = response.data + async RenderPlace(id) { + const response = await axios(`${process.env.BASE_URL}/API/Game/${id}?t=${process.env.ARBITER_TOKEN}`).catch((_) => reject(_)); + const { server_token, server_port, server_owner_id } = response.data; - this.id = server_token + this.id = server_token; - const started = await this.Start() - if (!started) throw new Error("RCCService failed to start") - if (!this.client) await this.CreateClient() + const started = await this.Start(); + if (!started) throw new Error("RCCService failed to start"); + if (!this.client) await this.CreateClient(); - logger.info(`[${this.id}] Place RenderJob started for ${id}`) + logger.info(`[${this.id}] Place RenderJob started for ${id}`); const result = await this.OpenJobEx({ name: this.id, @@ -147,16 +138,13 @@ class RenderJob extends Job { { type: "LUA_TNUMBER", value: id }, ], }, - }).catch((e) => false) + }).catch((e) => false); - logger.info(`[${this.id}] Place RenderJob finished for ${id}`) + logger.info(`[${this.id}] Place RenderJob finished for ${id}`); - await this.Stop() - - if (!result) return false - if (base64) return result[0].OpenJobExResult.LuaValue[0].value - return Buffer.from(result[0]?.OpenJobExResult?.LuaValue[0]?.value, "base64") + if (!result) return false; + return result[0]?.OpenJobExResult?.LuaValue[0]?.value; } } -module.exports = RenderJob +module.exports = RenderJob; diff --git a/src/routes/render/3d/asset.js b/src/routes/render/3d/asset.js deleted file mode 100644 index 4b11be8..0000000 --- a/src/routes/render/3d/asset.js +++ /dev/null @@ -1,14 +0,0 @@ -const express = require("express") -const app = express.Router() - -const RenderJob = require("../../../lib/classes/RenderJob.js") - -app.get("/:id", async (request, response) => { - const job = new RenderJob() - const result = await job.RenderAsset(request.params.id, process.env.RENDER_BASE64, true).catch((_) => _) - - if (result?.message) return response.status(500).json({ error: result.message }) - else return response.end(result) -}) - -module.exports = app diff --git a/src/routes/render/3d/user.js b/src/routes/render/3d/user.js deleted file mode 100644 index 6fb684d..0000000 --- a/src/routes/render/3d/user.js +++ /dev/null @@ -1,14 +0,0 @@ -const express = require("express") -const app = express.Router() - -const RenderJob = require("../../../lib/classes/RenderJob.js") - -app.get("/:id", async (request, response) => { - const job = new RenderJob() - const result = await job.RenderBodyshot(request.params.id, process.env.RENDER_BASE64, true).catch((_) => _) - - if (result?.message) return response.status(500).json({ error: result.message }) - else return response.end(result) -}) - -module.exports = app diff --git a/src/routes/render/asset.js b/src/routes/render/asset.js index af9df45..84e36ce 100644 --- a/src/routes/render/asset.js +++ b/src/routes/render/asset.js @@ -1,14 +1,32 @@ -const express = require("express") -const app = express.Router() +const express = require("express"); +const app = express.Router(); -const RenderJob = require("../../lib/classes/RenderJob.js") +const RenderJob = require("../../lib/classes/RenderJob.js"); app.get("/:id", async (request, response) => { - const job = new RenderJob() - const result = await job.RenderAsset(request.params.id, process.env.RENDER_BASE64).catch((_) => _) + const { params, query } = request; + const job = new RenderJob(); + let body = {}; - if (result?.message) return response.status(500).json({ error: result.message }) - else return response.end(result) -}) + const aseet = await job.RenderAsset(params.id).catch((_) => _); + if (aseet?.message) { + job.Stop(); + return response.status(500).json({ error: aseet.message }); + } + body.aseet = aseet; -module.exports = app + if (query.three_d) { + const three_d = await job.RenderAsset(params.id, true).catch((_) => _); + if (three_d?.message) { + job.Stop(); + return response.status(500).json({ error: three_d.message }); + } + body.three_d = three_d; + } + + job.Stop(); + + return response.json(body); +}); + +module.exports = app; diff --git a/src/routes/render/bodyshot.js b/src/routes/render/bodyshot.js deleted file mode 100644 index b935c83..0000000 --- a/src/routes/render/bodyshot.js +++ /dev/null @@ -1,14 +0,0 @@ -const express = require("express") -const app = express.Router() - -const RenderJob = require("../../lib/classes/RenderJob.js") - -app.get("/:id", async (request, response) => { - const job = new RenderJob() - const result = await job.RenderBodyshot(request.params.id, process.env.RENDER_BASE64).catch((_) => _) - - if (result?.message) return response.status(500).json({ error: result.message }) - else return response.end(result) -}) - -module.exports = app diff --git a/src/routes/render/headshot.js b/src/routes/render/headshot.js deleted file mode 100644 index 99a5195..0000000 --- a/src/routes/render/headshot.js +++ /dev/null @@ -1,14 +0,0 @@ -const express = require("express") -const app = express.Router() - -const RenderJob = require("../../lib/classes/RenderJob.js") - -app.get("/:id", async (request, response) => { - const job = new RenderJob() - const result = await job.RenderHeadshot(request.params.id, process.env.RENDER_BASE64).catch((_) => _) - - if (result?.message) return response.status(500).json({ error: result.message }) - else return response.end(result) -}) - -module.exports = app diff --git a/src/routes/render/texture.js b/src/routes/render/texture.js new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/render/user.js b/src/routes/render/user.js new file mode 100644 index 0000000..0933628 --- /dev/null +++ b/src/routes/render/user.js @@ -0,0 +1,39 @@ +const express = require("express"); +const app = express.Router(); + +const RenderJob = require("../../lib/classes/RenderJob.js"); + +app.get("/:id", async (request, response) => { + const { params, query } = request; + const job = new RenderJob(); + let body = {}; + + const headshot = await job.RenderHeadshot(params.id).catch((_) => _); + if (headshot?.message) { + job.Stop(); + return response.status(500).json({ error: headshot.message }); + } + body.headshot = headshot; + + const bodyshot = await job.RenderBodyshot(params.id).catch((_) => _); + if (bodyshot?.message) { + job.Stop(); + return response.status(500).json({ error: bodyshot.message }); + } + body.bodyshot = bodyshot; + + if (query.three_d) { + const three_d = await job.RenderBodyshot(params.id, true).catch((_) => _); + if (three_d?.message) { + job.Stop(); + return response.status(500).json({ error: three_d.message }); + } + body.three_d = three_d; + } + + job.Stop(); + + return response.json(body); +}); + +module.exports = app;