:DDDDDDDDDDDDDDDdDDDD

This commit is contained in:
I-Have-An-Issue 2023-01-22 03:21:53 -05:00
parent 38ed92abdf
commit d8931427dc
No known key found for this signature in database
GPG Key ID: E55435DEA0825091
23 changed files with 251 additions and 151 deletions

14
.env.example Normal file
View File

@ -0,0 +1,14 @@
RCCSERVICE=
BASE_URL=
RENDER_FORMAT=
RENDER_USER_WIDTH=
RENDER_USER_HEIGHT=
RENDER_ASSET_WIDTH=
RENDER_ASSET_HEIGHT=
RENDER_PLACE_WIDTH=
RENDER_PLACE_HEIGHT=

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
node_modules
build
build
.env

View File

@ -1 +1,7 @@
# bingle-arbiter
The Bingle arbiter is designed to be used with almost any revival backend.
It comes preloaded with some Lua scripts made by kinery.
Set your desired settings in `.env.example`, then rename it to `.env`.

View File

@ -1,2 +0,0 @@
set RCCSERVICE_PATH=D:\\Projects\\Roblox\\Source\\UploadBits\\Win32-Release-RCCService\\
npm run dev

2
dev.sh
View File

@ -1,2 +0,0 @@
export RCCSERVICE_PATH=/run/media/calones/32531f99-d721-4297-90c7-f91e56851060/ICCService/
npm run dev

9
package-lock.json generated
View File

@ -10,6 +10,7 @@
"license": "ISC",
"dependencies": {
"chalk": "^4.1.2",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"soap": "^1.0.0",
"wait-port": "^1.0.4"
@ -305,6 +306,14 @@
"wrappy": "1"
}
},
"node_modules/dotenv": {
"version": "16.0.3",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz",
"integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==",
"engines": {
"node": ">=12"
}
},
"node_modules/ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",

View File

@ -15,6 +15,7 @@
"license": "ISC",
"dependencies": {
"chalk": "^4.1.2",
"dotenv": "^16.0.3",
"express": "^4.18.2",
"soap": "^1.0.0",
"wait-port": "^1.0.4"

View File

@ -1,2 +0,0 @@
set RCCSERVICE_PATH=C:\\RCCService\\
npm run start

View File

@ -1,13 +1,18 @@
const logger = require("./lib/logger.js")
require("dotenv").config()
const express = require("express")
const app = express()
app.use("/game/start", require("./routes/game/start.js"))
app.use("/game/stop", require("./routes/game/stop.js"))
app.use("/game/execute", require("./routes/game/execute.js"))
const logger = require("./lib/logger.js")
if (process.platform == "linux") logger.warn("Game hosting might not fully compatible with Linux")
app.use("/place/start", require("./routes/place/start.js"))
app.use("/place/stop", require("./routes/place/stop.js"))
app.use("/place/execute", require("./routes/place/execute.js"))
app.use("/place/renew", require("./routes/place/renew.js"))
app.use("/render/asset", require("./routes/render/asset.js"))
app.use("/render/game", require("./routes/render/game.js"))
app.use("/render/place", require("./routes/render/place.js"))
app.use("/render/headshot", require("./routes/render/headshot.js"))
app.use("/render/bodyshot", require("./routes/render/bodyshot.js"))
@ -18,5 +23,5 @@ app.listen(process.env.PORT || 64989, () => {
})
process.on("uncaughtException", (err) => {
logger.error(err)
logger.error(err.message)
})

View File

@ -1,9 +1,11 @@
const RCCService = require("./RCCService.js")
const soap = require("soap")
const { randomUUID } = require("crypto")
const RCCService = require("./RCCService.js")
class Job extends RCCService {
constructor(id, port, expirationInSeconds = 10, category = 0, cores = 1) {
super(port)
constructor({ id = randomUUID(), expirationInSeconds = 10, category = 0, cores = 1 } = {}) {
super()
this.id = id
this.expirationInSeconds = expirationInSeconds
this.category = category
@ -15,7 +17,7 @@ class Job extends RCCService {
return this.client
}
async Open(script) {
async OpenJobEx(script) {
if (!this.client) throw new Error("There is no client")
return await this.client.OpenJobExAsync({
job: {
@ -28,16 +30,19 @@ class Job extends RCCService {
})
}
async Close() {
async CloseJob() {
if (!this.client) return true
return await this.client.CloseAllJobsAsync({})
return await this.client.CloseJobAsync({ jobID: this.id })
}
async RenewLease(expirationInSeconds) {
return await this.client.RenewLeaseAsync({
jobID: this.id,
expirationInSeconds,
})
if (!this.client) throw new Error("There is no client")
return await this.client.RenewLeaseAsync({ jobID: this.id, expirationInSeconds })
}
async Execute(name, script) {
if (!this.client) throw new Error("There is no client")
return await this.client.ExecuteAsync({ jobID: this.id, script: { name, script, arguments: {} } })
}
}

View File

@ -1,30 +1,31 @@
const EventEmitter = require("events")
const child_process = require("child_process")
const waitPort = require("wait-port")
const logger = require("../../lib/logger.js")
const randport = require("../../lib/randport.js")
class RCCService extends EventEmitter {
constructor(port, path = process.env.RCCSERVICE_PATH) {
constructor() {
super()
this.path = path
this.port = port
}
Start(options = { cwd: this.path }) {
return new Promise((resolve, reject) => {
Start() {
return new Promise(async (resolve, reject) => {
try {
this.port = await randport.tcp()
if (process.platform == "win32") {
this.proc = child_process.spawn("RCCService.exe", ["-Console", "-PlaceId:-1", `-Port`, this.port], options)
this.proc = child_process.spawn("RCCService.exe", ["-Console", "-PlaceId:-1", `-Port`, this.port], { cwd: process.env.RCCSERVICE })
} else {
this.proc = child_process.spawn("wine", ["RCCService.exe", "-Console", "-PlaceId:-1", `-Port`, this.port], options)
this.proc = child_process.spawn("wine", ["RCCService.exe", "-Console", "-PlaceId:-1", `-Port`, this.port], { cwd: process.env.RCCSERVICE })
}
this.proc.once("spawn", async () => {
logger.info(`[${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, exiting`)
this.Close()
logger.error(`[${this.port}] RCCService could not listen`)
return resolve(false)
}

View File

@ -1,7 +1,152 @@
const { readFileSync } = require("fs")
const Job = require("./Job.js")
const logger = require("../logger.js")
class RenderJob extends Job {
constructor() {}
constructor() {
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()
logger.info(`[${this.id}] Headshot RenderJob started for ${id}`)
const result = await this.OpenJobEx({
name: this.id,
script: readFileSync(__dirname + "/../../lua/headshot.lua", { encoding: "utf-8" }),
arguments: {
LuaValue: [
{ type: "LUA_TSTRING", value: this.id },
{ type: "LUA_TSTRING", value: "Headshot" },
{ type: "LUA_TSTRING", value: process.env.RENDER_FORMAT },
{ type: "LUA_TNUMBER", value: process.env.RENDER_USER_WIDTH },
{ type: "LUA_TNUMBER", value: process.env.RENDER_USER_HEIGHT },
{ type: "LUA_TSTRING", value: process.env.BASE_URL },
{ type: "LUA_TNUMBER", value: id },
],
},
}).catch((e) => false)
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")
}
async RenderBodyshot(id, base64 = false) {
const started = await this.Start()
if (!started) throw new Error("RCCService failed to start")
if (!this.client) await this.CreateClient()
logger.info(`[${this.id}] Bodyshot RenderJob started for ${id}`)
const result = await this.OpenJobEx({
name: this.id,
script: readFileSync(__dirname + "/../../lua/bodyshot.lua", { encoding: "utf-8" }),
arguments: {
LuaValue: [
{ type: "LUA_TSTRING", value: this.id },
{ type: "LUA_TSTRING", value: "Bodyshot" },
{ type: "LUA_TSTRING", value: process.env.RENDER_FORMAT },
{ type: "LUA_TNUMBER", value: process.env.RENDER_USER_WIDTH },
{ type: "LUA_TNUMBER", value: process.env.RENDER_USER_HEIGHT },
{ type: "LUA_TSTRING", value: process.env.BASE_URL },
{ type: "LUA_TNUMBER", value: id },
],
},
}).catch((e) => false)
logger.info(`[${this.id}] Bodyshot 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")
}
async RenderAsset(id, base64 = false) {
const started = await this.Start()
if (!started) throw new Error("RCCService failed to start")
if (!this.client) await this.CreateClient()
logger.info(`[${this.id}] Asset RenderJob started for ${id}`)
const result = await this.OpenJobEx({
name: this.id,
script: readFileSync(__dirname + "/../../lua/xml.lua", { encoding: "utf-8" }),
arguments: {
LuaValue: [
{ type: "LUA_TSTRING", value: this.id },
{ type: "LUA_TSTRING", value: "Asset" },
{ type: "LUA_TSTRING", value: process.env.RENDER_FORMAT },
{ type: "LUA_TNUMBER", value: process.env.RENDER_ASSET_WIDTH },
{ type: "LUA_TNUMBER", value: process.env.RENDER_ASSET_HEIGHT },
{ type: "LUA_TSTRING", value: process.env.BASE_URL },
{ type: "LUA_TNUMBER", value: id },
],
},
}).catch((e) => false)
logger.info(`[${this.id}] Asset 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")
}
async RenderPlace(id, base64 = false) {
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}`)
const result = await this.OpenJobEx({
name: this.id,
script: readFileSync(__dirname + "/../../lua/place.lua", { encoding: "utf-8" }),
arguments: {
LuaValue: [
{ type: "LUA_TSTRING", value: this.id },
{ type: "LUA_TSTRING", value: "Place" },
{ type: "LUA_TSTRING", value: process.env.RENDER_FORMAT },
{ type: "LUA_TNUMBER", value: process.env.RENDER_PLACE_WIDTH },
{ type: "LUA_TNUMBER", value: process.env.RENDER_PLACE_HEIGHT },
{ type: "LUA_TSTRING", value: process.env.BASE_URL },
{ type: "LUA_TNUMBER", value: id },
],
},
}).catch((e) => false)
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")
}
}
module.exports = RenderJob

View File

@ -1,6 +1,7 @@
const net = require("net")
const dgram = require("dgram")
module.exports = () => {
exports.tcp = () => {
return new Promise((resolve) => {
const server = net.createServer()
server.listen(0, () => {
@ -9,3 +10,13 @@ module.exports = () => {
})
})
}
exports.udp = () => {
return new Promise((resolve) => {
const server = dgram.createSocket()
server.bind(0, () => {
const port = server.address().port
server.close((err) => resolve(port))
})
})
}

View File

@ -1,5 +0,0 @@
module.exports = (ms) => {
return new Promise((resolve) => {
setTimeout(resolve, ms)
})
}

View File

@ -13,7 +13,7 @@ asset.Parent = workspace
local thumbnailCamera = asset:FindFirstChild("ThumbnailCamera")
if thumbnailCamera ~= nil and thumbnailCamera.ClassName == "Camera" then
workspace.CurrentCamera = ModelCamera
workspace.CurrentCamera = thumbnailCamera
end
print(("[%s] Rendering ..."):format(jobId))

View File

@ -1,45 +1,14 @@
const { readFileSync } = require("fs")
const { randomUUID } = require("crypto")
const logger = require("../../lib/logger.js")
const randport = require("../../lib/randport.js")
const Job = require("../../lib/classes/Job.js")
const express = require("express")
const app = express.Router()
const RenderJob = require("../../lib/classes/RenderJob.js")
app.get("/:id", async (request, response) => {
const job = new Job(randomUUID(), await randport())
const started = await job.Start()
if (!started) return response.status(500).json({ error: "RCCService failed to start" })
const job = new RenderJob()
const result = await job.RenderAsset(request.params.id).catch((_) => _)
logger.info(`[${job.id}] Job opened`)
await job.CreateClient()
const result = await job
.Open({
name: job.id,
script: readFileSync(__dirname + "/../../lua/xml.lua", { encoding: "utf-8" }),
arguments: {
LuaValue: [
{ type: "LUA_TSTRING", value: job.id },
{ type: "LUA_TSTRING", value: "XML" },
{ type: "LUA_TSTRING", value: "PNG" },
// change this to 1920x when we finish the arbiter
{ type: "LUA_TNUMBER", value: "420" },
{ type: "LUA_TNUMBER", value: "420" },
{ type: "LUA_TSTRING", value: "https://economy.ittblox.gay" },
{ type: "LUA_TNUMBER", value: request.params.id },
],
},
})
.catch((e) => false)
logger.info(`[${job.id}] Job closed`)
await job.Stop()
if (result) return response.end(Buffer.from(result[0]?.OpenJobExResult?.LuaValue[0]?.value, "base64"))
else return response.status(500).end()
if (result?.message) return response.status(500).json({ error: result.message })
else return response.end(result)
})
module.exports = app

View File

@ -1,45 +1,14 @@
const { readFileSync } = require("fs")
const { randomUUID } = require("crypto")
const logger = require("../../lib/logger.js")
const randport = require("../../lib/randport.js")
const Job = require("../../lib/classes/Job.js")
const express = require("express")
const app = express.Router()
const RenderJob = require("../../lib/classes/RenderJob.js")
app.get("/:id", async (request, response) => {
const job = new Job(randomUUID(), await randport())
const started = await job.Start()
if (!started) return response.status(500).json({ error: "RCCService failed to start" })
const job = new RenderJob()
const result = await job.RenderBodyshot(request.params.id).catch((_) => _)
logger.info(`[${job.id}] Job opened`)
await job.CreateClient()
const result = await job
.Open({
name: job.id,
script: readFileSync(__dirname + "/../../lua/bodyshot.lua", { encoding: "utf-8" }),
arguments: {
LuaValue: [
{ type: "LUA_TSTRING", value: job.id },
{ type: "LUA_TSTRING", value: "Bodyshot" },
{ type: "LUA_TSTRING", value: "PNG" },
// change this to 1920x when we finish the arbiter
{ type: "LUA_TNUMBER", value: "420" },
{ type: "LUA_TNUMBER", value: "420" },
{ type: "LUA_TSTRING", value: "https://economy.ittblox.gay" },
{ type: "LUA_TNUMBER", value: request.params.id },
],
},
})
.catch((e) => false)
logger.info(`[${job.id}] Job closed`)
await job.Stop()
if (result) return response.end(Buffer.from(result[0]?.OpenJobExResult?.LuaValue[0]?.value, "base64"))
else return response.status(500).end()
if (result?.message) return response.status(500).json({ error: result.message })
else return response.end(result)
})
module.exports = app

View File

@ -1,45 +1,14 @@
const { readFileSync } = require("fs")
const { randomUUID } = require("crypto")
const logger = require("../../lib/logger.js")
const randport = require("../../lib/randport.js")
const Job = require("../../lib/classes/Job.js")
const express = require("express")
const app = express.Router()
const RenderJob = require("../../lib/classes/RenderJob.js")
app.get("/:id", async (request, response) => {
const job = new Job(randomUUID(), await randport())
const started = await job.Start()
if (!started) return response.status(500).json({ error: "RCCService failed to start" })
const job = new RenderJob()
const result = await job.RenderHeadshot(request.params.id).catch((_) => _)
logger.info(`[${job.id}] Job opened`)
await job.CreateClient()
const result = await job
.Open({
name: job.id,
script: readFileSync(__dirname + "/../../lua/headshot.lua", { encoding: "utf-8" }),
arguments: {
LuaValue: [
{ type: "LUA_TSTRING", value: job.id },
{ type: "LUA_TSTRING", value: "Headshot" },
{ type: "LUA_TSTRING", value: "PNG" },
// change this to 1920x when we finish the arbiter
{ type: "LUA_TNUMBER", value: "420" },
{ type: "LUA_TNUMBER", value: "420" },
{ type: "LUA_TSTRING", value: "https://economy.ittblox.gay" },
{ type: "LUA_TNUMBER", value: request.params.id },
],
},
})
.catch((e) => false)
logger.info(`[${job.id}] Job closed`)
await job.Stop()
if (result) return response.end(Buffer.from(result[0]?.OpenJobExResult?.LuaValue[0]?.value, "base64"))
else return response.status(500).end()
if (result?.message) return response.status(500).json({ error: result.message })
else return response.end(result)
})
module.exports = app

View File

@ -0,0 +1,6 @@
const express = require("express")
const app = express.Router()
app.all("*", (request, response) => response.status(404).json({ status: 404 }))
module.exports = app