feat(global): add utility functions to library code + overhaul stuff

A bit painful to test inside a Gitpod workspace through, but it worked,
at least we'll not distrub Discord Support regarding approval for using RPC yet
for now. Includes syntax fixes on state stuff and even improving parts of the code.
README will be next btw.

Signed-off-by: Andrei Jiroh Eugenio Halili <ajhalili2006@gmail.com>
This commit is contained in:
Andrei Jiroh Halili 2022-03-22 15:29:40 +00:00
parent cd810e3a88
commit b8ebf92df3
4 changed files with 138 additions and 31 deletions

61
app.js
View File

@ -1,22 +1,24 @@
const express = require("express")
const app = new express()
const RPC = require('discord-rpc');
const client = new RPC.Client({ transport: 'ipc' });
const { AutoClient } = require("discord-auto-rpc")
const client = new AutoClient({ transport: 'ipc' });
const { defaultActivity } = require("./lib/defaults");
const { teamsIndex } = require("./lib/teams")
const port = process.env.PORT || 60881
const { getState, updateState, preloadState } = require("./lib/utils");
const { getState, updateState, sixHoursAgo, timestampStart } = require("./lib/utils");
const fs = require("node:fs");
const { get } = require("node:http");
app.get("/changeTeams/regular-participant/:teamSlug", (res, req) => {
if (req.teamSlug == "sprecators") {
app.get("/changeTeams/regular-participant/:teamSlug", (req, res) => {
if (req.params.teamSlug == "spectator") {
client.setActivity({
pid: process.pid,
activity: teamsIndex.regularEvents.sprecators
activity: teamsIndex.regularEvents.spectator
})
updateState(teamsIndex.regularEvents.spectator)
res.json({
ok: true,
state: getState()
})
updateState(teamsIndex.regularEvents.sprecators)
} else {
res.status(404).json({
ok: false,
@ -29,16 +31,29 @@ app.get("/getState", (req, res) => {
res.json(getState())
})
app.get("/getState/preloaded", (req, res) => {
res.json(preloadState)
})
client.on('ready', async () => {
fs.stat('rpcState.json', function(err, stat) {
fs.stat('rpcState.json', (err, stat) => {
if (err == null) {
resetStartTimestamp = {
details: getState().details,
assets: getState().assets,
state: getState().state,
buttons: getState().buttons,
timestamps: {
start: timestampStart()
}
}
console.log('info: State file exists, preloading from previous state');
client.request("SET_ACTIVITY", { pid: process.pid, activity: getState() });
/** Check if timestamp.start from getState is longer than six hours to trigger reset. */
if (sixHoursAgo > getState().timestamps.start) {
console.log("info: timestamp.start from state file is less than 6 hours ago, preloading")
client.request("SET_ACTIVITY", { pid: process.pid, activity: getState() });
} else if (sixHoursAgo < getState().timestamps.start) {
console.log('info: timestamp.start from state file is longer than 6 hours, resetting...')
updateState(resetStartTimestamp)
}
} else {
client.request("SET_ACTIVITY", { pid: process.pid, activity: defaultActivity });
console.log("info: Using default activity for state due to file issues");
@ -46,14 +61,20 @@ client.on('ready', async () => {
}
});
});
client.on('connected', async () => {
console.log("info: Connected to Discord RPC");
client.once('connected', async () => {
console.log("info: Connected to Discord local RPC server");
});
app.listen(port, () => {
console.log("info: REST API is up at http://localhost:"+port+", see README.md and docs directory")
console.log("info: for the API docs.")
console.log("info: for the API docs. Please do not make API calls yet until the API server successfully")
console.log("info: connects to Discord RPC to avoid issues..")
})
// Uses the unofficial MCC.Live OAuth client ID from Andrei Jiroh.
client.login({ clientId: "952456760948559932" });
// Uses discord-auto-rpc behind the scenes to attempt to connect to RPC and wait until Discord is up.
client.endlessLogin({ clientId: "952456760948559932" });
module.exports = {
app,
client
}

View File

@ -1,3 +1,5 @@
const { timestampStart } = require("./utils")
let defaultActivity = {
details: "Event starts soon",
assets: {
@ -6,21 +8,19 @@ let defaultActivity = {
small_image: "spectator",
small_text: "Probably watching on Admin Stream soon"
},
state: "Idling behind the scenes",
buttons: [
{
"label": "Check event stats",
"url": "https://mcc.live"
},
{
"label": "View source",
"label": "Use this Custom RPC",
"url": "https://gitlab.com/RecapTime/mcc-discord-rpc"
}
],
timestamps: {
// set start time to when it's started
start: Date.now(),
// TODO: Update the end time, assuming that @TubboLive leaks it again.
end: 1651032000000 // MCC20 in UTC time
start: timestampStart()
}
}

View File

@ -1,10 +1,38 @@
const { timestampStart } = require("./utils")
let teamsIndex = {
regularEvents: {
sprecators: {
description: "Watching Admin Stream",
spectator: {
details: "On the Admin Stream",
state: "https://twitch.tv/TheNoxcrew",
assets: {
large_image: "mcc-twitter",
large_text: "MC Championship"
large_text: "MC Championship",
small_image: "spectator",
small_text: "Admin Stream"
},
buttons: [
{
"label": "Check event stats",
"url": "https://mcc.live"
},
{
"label": "Use this Custom RPC",
"url": "https://gitlab.com/RecapTime/mcc-discord-rpc"
}
],
timestamps: {
start: timestampStart()
}
},
red: {
description: "Participating as a Red Rabbit",
state: "Join me over the stream",
assets: {
large_image: "mcc-twitter",
large_text: "MC Championship",
small_image: "red-rabbits",
small_text: "Red Rabbit"
},
buttons: [
{
@ -12,16 +40,21 @@ let teamsIndex = {
"url": "https://mcc.live"
},
{
"label": "View source",
"label": "Use this Custom RPC",
"url": "https://gitlab.com/RecapTime/mcc-discord-rpc"
}
],
timestamp: {
start: Date.now()
start: timestampStart()
}
}
},
specialEvents: {}
}
module.exports = teamsIndex
let teamsWatchingIndex = {}
module.exports = {
teamsIndex,
teamsWatchingIndex
}

53
lib/utils.js Normal file
View File

@ -0,0 +1,53 @@
const timestampStartDefault = Date.now();
const { client } = require("../app")
const fs = require("node:fs")
let sixHoursAgo = Date.now() + (1 * 6 * 60 * 60 * 1000)
/**
* Get current RPC state fro rpcState.json file on the source code root.
* @returns {object} data - Parsed JSON object
*/
function getState () {
data = fs.readFileSync('rpcState.json', 'utf-8', (err, data) => {
if (err) {
return "{}";
}
return JSON.parse(data)
})
return JSON.parse(data)
}
function updateState (data) {
client.request('SET_ACTIVITY', { pid: process.pid, activity: data })
const stringifiedJson = Buffer.from(JSON.stringify(data))
fs.writeFile("rpcState.json", stringifiedJson, (err) => {
if (err) {
console.log("warn: State file doesn't exist yet.")
}
})
}
function timestampStart() {
try {
if (getState() == {} || getState().timestamps.start === undefined) {
return timestampStartDefault
} else if (getState().timestamps.start !== undefined ) {
if (sixHoursAgo > getState().timestamps.start) {
return getState().timestamps.start
} else if (sixHoursAgo < getState().timestamps.start) {
return timestampStartDefault
}
}
} catch {
return timestampStartDefault
}
}
module.exports = {
timestampStart,
updateState,
getState,
sixHoursAgo
}