const express = require('express'), path = require("path"), fs = require("fs"), WebSocket = require("ws"), chokidar = require("chokidar"), sharp = require("sharp") const PORT = process.env.PORT || 8080 var app = express() var lanyardData = "Nothing Fetched yet!" var sockets = [] var pfpSeason = "default" var violetSpins = 0 var lastActivity var configPath = path.join(__dirname, "config") if (!fs.existsSync(configPath)) { fs.mkdirSync(configPath) } var dataPath = path.join(__dirname, "data") if (!fs.existsSync(dataPath)) { fs.mkdirSync(dataPath) } else if (fs.existsSync(path.join(dataPath, "spins"))) { violetSpins = Number(fs.readFileSync(path.join(dataPath, "spins"))) } var configsC = ["socials.json"] var configsB = ["videos.json"] for (var i = 0; i < configsC.length; i++) { var file = configsC[i] var filePath = path.join(configPath, file) if (!fs.existsSync(filePath)) { fs.writeFileSync(filePath, "{}") } } for (var i = 0; i < configsB.length; i++) { var file = configsB[i] var filePath = path.join(configPath, file) if (!fs.existsSync(filePath)) { fs.writeFileSync(filePath, "[]") } } function randomFileInDir(directory) { var dir = fs.readdirSync(directory) return path.join(directory, dir[Math.floor(Math.random() * dir.length)]) } app.get("/", (req, res) => { var docs = fs.readFileSync(path.join(__dirname, "basicDocs.json")) docs = JSON.parse(docs) res.send(docs) }) app.get("/v1/pfp", async (req, res) => { res.setHeader("Content-Type", "image/png") var time = new Date(Date.now()) if ([12].includes(time.getMonth() + 1)) { pfpSeason = "christmas" } var pfpConfig = JSON.parse(fs.readFileSync(path.join(__dirname, "PFPs.json")))[pfpSeason] var characterNumb = (time.getDay()) % pfpConfig.length var char = pfpConfig[characterNumb] var pfps = char.pfps var pfpPool = pfps var rand = Math.floor(Math.random() * pfpPool.length) var pfp = path.join(__dirname, char.pfpRoot, pfpPool[rand]) var pfpRaw = fs.readFileSync(pfp) var pfpWidth = Number(req.query.width) || 256 var pfpHeight = Number(req.query.height) || 256 const converted = await sharp(pfpRaw) .resize(pfpWidth, pfpHeight) .png({ progressive: true }) .toBuffer() res.send(converted) }) app.get("/v1/lanyard", (req, res) => { res.send(lanyardData) }) app.get("/v1/spins", (req, res) => { res.send(violetSpins.toString()) }) app.get("/v1/socials", (req, res) => { res.sendFile(path.join(configPath, "socials.json")) }) function getVideo() { var videoQueue = JSON.parse(fs.readFileSync(path.join(dataPath, "videos.json"))) var newQueue = [] for (var i = 0; i < videoQueue.length; i++) { var video = videoQueue[i] if (video.ends > Date.now()) { newQueue.push(video) } } videoQueue = newQueue fs.writeFileSync(path.join(dataPath, "videos.json"), JSON.stringify(newQueue)) var oldest = videoQueue[0] for (var i = 0; i < videoQueue.length; i++) { var video = videoQueue[i] if (video.ends < (oldest.ends)) { oldest = video } } return oldest } // app.listen(PORT, () => { // console.log("API is now listening on port 8080!") // }) function socketeer() { var lanyard = new WebSocket('wss://lanyard.violets-purgatory.dev/socket') function beat(dur) { lanyard.send(JSON.stringify({ op: 3 })) setTimeout(() => { beat(dur) }, dur); } lanyard.addEventListener("message", async (res) => { var data = JSON.parse(res.data) if (data.op == 1) { beat(data.d.heartbeat_interval) lanyard.send(JSON.stringify({ op: 2, d: { subscribe_to_id: "534132311781015564" } })) } else if (data.op == 0) { lanyardData = data lanyardData.d.socials = JSON.parse(fs.readFileSync(path.join(configPath, "socials.json"))) lanyardData.d.video = getVideo() var newArr = [] for (var i = 0; i < lanyardData.d.activities.length; i++) { var activity = lanyardData.d.activities[i] if (activity.type == 2) { // if (activity.name == "Spotify") { if (activity.assets) { activity.song = activity.details activity.album = activity.assets.large_text activity.artist = activity.state } } if (activity.type != 4) { newArr.push(activity) } else if (activity.type == 4) { lanyardData.d.custom_status = { "text": activity.state } if (activity.emoji) { lanyardData.d.custom_status.emoji = activity.emoji } } } lanyardData.d.activities = newArr if (lanyardData.d.discord_status == "offline") { lanyardData.d.activityChanged = false } else { lanyardData.d.activityChanged = lastActivity != JSON.stringify(lanyardData.d.activities) } lastActivity = JSON.stringify(lanyardData.d.activities) for (let index = 0; index < sockets.length; index++) { var socketData = sockets[index] var socket = socketData.socket; socket.send(JSON.stringify(lanyardData)) if ((Date.now() - socketData.lastPing) > 120000) { sockets.splice(index, 1) } } } }) lanyard.on('close', () => { console.log("Disconnected") setTimeout(() => { socketeer() }, 60000) }) } socketeer() // wsServer = new WebSocket.WebSocketServer({ port: 8090 }) wsServer = WebSocket.Server; let server = require('http').createServer() wsServer = new wsServer({ server: server, perMessageDeflate: false }) server.on('request', app) wsServer.on("connection", function connection(socket) { socket.on('message', function message(data) { data = JSON.parse(data) if (data.op == 3) { for (let index = 0; index < sockets.length; index++) { const socketData = sockets[index]; if (socketData.socket == socket) { sockets[index].lastPing = Date.now() } } socket.send(`{"op": 3}`) } else if (data.op == 4) { violetSpins += 1 if (violetSpins % 10 == 0) { fs.writeFileSync(path.join(dataPath, "spins"), violetSpins.toString()) } for (var i = 0; i < sockets.length; i++) { var soc = sockets[i].socket soc.send(`{"op": 4, "spins": ${violetSpins}}`) } } else { console.log(data) } }) socket.send(JSON.stringify(lanyardData)) socket.send(`{ "op": 1 }`) socket.send(`{"op": 4, "spins": ${violetSpins}}`) sockets.push({ socket, lastPing: Date.now() }) }) server.listen(PORT, function () { console.log("API & Websocket now on port: " + PORT) }) process.on('uncaughtException', (err, origin) => { fs.writeSync( process.stderr.fd, `Caught exception: ${err}\n` + `Exception origin: ${origin}`, ); }); chokidar.watch(path.join(configPath, "videos.json")).on("change", () => { var videos = JSON.parse(fs.readFileSync(path.join(configPath, "videos.json"))) if (!fs.existsSync(path.join(dataPath, "videos.json"))) { fs.writeFileSync(path.join(dataPath, "videos.json"), "[]") } var videoQueue = JSON.parse(fs.readFileSync(path.join(dataPath, "videos.json"))) var latestTime = Date.now() for (var i = 0; i < videoQueue.length; i++) { var vid = videoQueue[i]; if (Number(vid.ends) > latestTime) { latestTime = Number(vid.ends) } } var newVideos = [] for (var i = 0; i < videos.length; i++) { latestTime += 604800000 var url = videos[i] newVideos.push({ "url": url, "ends": latestTime }) } videoQueue = videoQueue.concat(newVideos) fs.writeFileSync(path.join(dataPath, "videos.json"), JSON.stringify(videoQueue)) fs.writeFileSync(path.join(configPath, "videos.json"), "[]") })