refactor a lot
Some checks failed
Code quality checks / biome (push) Failing after 7s

This commit is contained in:
Seth 2025-05-04 20:47:19 -04:00
parent cf21a56d7a
commit deb223c642
27 changed files with 401 additions and 381 deletions

View file

@ -4,7 +4,9 @@
"": { "": {
"name": "ipv4.army", "name": "ipv4.army",
"dependencies": { "dependencies": {
"@speed-highlight/core": "^1.2.7",
"microlight": "^0.0.7", "microlight": "^0.0.7",
"reconnecting-websocket": "^4.4.0",
"tsx-dom": "^3.1.0", "tsx-dom": "^3.1.0",
}, },
"devDependencies": { "devDependencies": {
@ -35,14 +37,18 @@
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="], "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@1.9.4", "", { "os": "win32", "cpu": "x64" }, "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA=="],
"@types/bun": ["@types/bun@1.2.10", "", { "dependencies": { "bun-types": "1.2.10" } }, "sha512-eilv6WFM3M0c9ztJt7/g80BDusK98z/FrFwseZgT4bXCq2vPhXD4z8R3oddmAn+R/Nmz9vBn4kweJKmGTZj+lg=="], "@speed-highlight/core": ["@speed-highlight/core@1.2.7", "", {}, "sha512-0dxmVj4gxg3Jg879kvFS/msl4s9F3T9UXC1InxgOf7t5NvcPD97u/WTA5vL/IxWHMn7qSxBozqrnnE2wvl1m8g=="],
"@types/bun": ["@types/bun@1.2.12", "", { "dependencies": { "bun-types": "1.2.12" } }, "sha512-lY/GQTXDGsolT/TiH72p1tuyUORuRrdV7VwOTOjDOt8uTBJQOJc5zz3ufwwDl0VBaoxotSk4LdP0hhjLJ6ypIQ=="],
"@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="], "@types/node": ["@types/node@22.14.1", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw=="],
"bun-types": ["bun-types@1.2.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-b5ITZMnVdf3m1gMvJHG+gIfeJHiQPJak0f7925Hxu6ZN5VKA8AGy4GZ4lM+Xkn6jtWxg5S3ldWvfmXdvnkp3GQ=="], "bun-types": ["bun-types@1.2.12", "", { "dependencies": { "@types/node": "*" } }, "sha512-tvWMx5vPqbRXgE8WUZI94iS1xAYs8bkqESR9cxBB1Wi+urvfTrF1uzuDgBHFAdO0+d2lmsbG3HmeKMvUyj6pWA=="],
"microlight": ["microlight@0.0.7", "", {}, "sha512-kigwsJYoy4mAMkGZpS839/KZ5WWQQm4TzD+eIjR5leS5H0j+EhExvK0Z2Or2ewkBR/t7/AHHhxRyeXi1kurG0g=="], "microlight": ["microlight@0.0.7", "", {}, "sha512-kigwsJYoy4mAMkGZpS839/KZ5WWQQm4TzD+eIjR5leS5H0j+EhExvK0Z2Or2ewkBR/t7/AHHhxRyeXi1kurG0g=="],
"reconnecting-websocket": ["reconnecting-websocket@4.4.0", "", {}, "sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng=="],
"tsx-dom": ["tsx-dom@3.1.0", "", { "dependencies": { "tsx-dom-types": "2.1.0" } }, "sha512-PGN7iL6zNC4Jj7bA1groSIz5mFB3Rr+SeoywZk2g4+c9uV8wwzCf+5tFQ8SyZxQIBHech3ueB0KxV3OFieqhOA=="], "tsx-dom": ["tsx-dom@3.1.0", "", { "dependencies": { "tsx-dom-types": "2.1.0" } }, "sha512-PGN7iL6zNC4Jj7bA1groSIz5mFB3Rr+SeoywZk2g4+c9uV8wwzCf+5tFQ8SyZxQIBHech3ueB0KxV3OFieqhOA=="],
"tsx-dom-types": ["tsx-dom-types@2.1.0", "", {}, "sha512-pZaMTrMRNom+D1b82K+1cWVMuogXrD/ANI42UYxilw27tF+tDCgj7GrD1XLmCxbHPDO2zxfmFuaz04KIEfWydQ=="], "tsx-dom-types": ["tsx-dom-types@2.1.0", "", {}, "sha512-pZaMTrMRNom+D1b82K+1cWVMuogXrD/ANI42UYxilw27tF+tDCgj7GrD1XLmCxbHPDO2zxfmFuaz04KIEfWydQ=="],

4
hyperate.json Normal file
View file

@ -0,0 +1,4 @@
{
"5338": 18153,
"null": 893
}

259
index.ts
View file

@ -1,8 +1,9 @@
import { build, serve, gzipSync, file, type BunRequest, gc } from "bun"; import { build, serve, gzipSync, file, gc } from "bun";
import Backend from "./src/back"
import pkg from "./package.json"; import pkg from "./package.json";
const development = process.env.NODE_ENV === "development";
let heartrate = 0; let heartrate = 0;
let lanyard = {}; let lanyard = {};
@ -11,162 +12,75 @@ require("node:fs/promises").rm("./dist", { recursive: true, force: true }).catch
// ignore // ignore
}); });
const buildWeb = async () => { if (!Backend.development) {
return await build({ await Backend.build()
entrypoints: ['./src/index.html'],
outdir: './dist',
minify: !development,
sourcemap: (development ? "inline" : "none"),
splitting: true,
publicPath: "/assets/",
loader: {
".woff2": "file"
},
})
} }
if (!development) { const server = serve({
await buildWeb()
}
const webserver = serve({
routes: { routes: {
"/": async () => { "/": async (req: Bun.BunRequest, server: Bun.Server) => {
if (development) { await Backend.postAnalytics(req, server);
await buildWeb()
if (Backend.development) {
await Backend.build()
} }
return new Response(gzipSync(await file("./dist/index.html").arrayBuffer()), {
headers: { return await Backend.Responses.file(file("./dist/index.html"));
"Content-Type": "text/html",
"Cache-Control": "no-cache",
"Content-Encoding": "gzip",
}
})
}, },
"/assets/:file": async (req: BunRequest<"/assets/:file">) => { "/assets/:file": async (req: Bun.BunRequest<"/assets/:file">) => {
const reqFile = file(`./dist/${req.params.file}`) return await Backend.Responses.file(file(`./dist/${req.params.file}`));
return new Response(gzipSync(await reqFile.arrayBuffer()), {
headers: {
"Content-Type": reqFile.type,
"Cache-Control": "public, max-age=31536000",
"Content-Encoding": "gzip",
}
})
}, },
"/public/:file": async (req: BunRequest<"/public/:file">) => { "/public/:file": async (req: Bun.BunRequest<"/public/:file">) => {
const reqFile = file(`./public/${req.params.file}`) return await Backend.Responses.file(file(`./public/${req.params.file}`));
let fileRes = await reqFile.text()
fileRes = fileRes.replace("{{LANYARD}}", `${JSON.stringify({ example: "lanyard data" })}`)
fileRes = fileRes.replace("{{HYPERATE}}", `${JSON.stringify({ example: "hyperate data" })}`)
return new Response(gzipSync(fileRes), {
headers: {
"Content-Type": reqFile.type,
"Cache-Control": "public, max-age=31536000",
"Content-Encoding": "gzip",
}
})
},
"/public/font/:file": async (req: BunRequest<"/public/font/:file">) => {
const reqFile = file(`./public/font/${req.params.file}`)
return new Response(gzipSync(await reqFile.arrayBuffer()), {
headers: {
"Content-Type": reqFile.type,
"Cache-Control": "public, max-age=31536000",
"Content-Encoding": "gzip",
}
})
}, },
"/api/server": () => { "/api/server": () => {
const string = JSON.stringify(process) const string = JSON.stringify(process)
const json = JSON.parse(string) const data = JSON.parse(string)
// clear possibly data that could be sensitive // clear possibly data that could be sensitive
json.argv = {} data.env = {}
json.debugPort = 0
json.env = {}
json.execArgv = []
json.execPath = ""
json.stderr = {}
json.stdin = {}
json.stdout = {}
json.title = ""
json.availableMemory = process.availableMemory() data.availableMemory = process.availableMemory()
json.constrainedMemory = process.constrainedMemory() data.constrainedMemory = process.constrainedMemory()
json.cpuUsage = process.cpuUsage() data.cpuUsage = process.cpuUsage()
json.memoryUsage = process.memoryUsage() data.memoryUsage = process.memoryUsage()
json.uptime = process.uptime() data.uptime = process.uptime()
json.package = pkg data.package = pkg
return new Response(gzipSync(JSON.stringify({ data: json })), { return Backend.Responses.json({ data });
headers: {
"Content-Type": "application/json",
"Cache-Control": "no-cache",
"Content-Encoding": "gzip",
}
})
}, },
"/api/health": () => { "/api/health": () => {
return new Response(gzipSync(JSON.stringify({ data: "ok" })), { return Backend.Responses.ok();
headers: {
"Content-Type": "application/json",
"Cache-Control": "no-cache",
"Content-Encoding": "gzip",
}
})
}, },
"/api/ws": (req, server) => { "/api/ws": async (req, server) => {
if (server.upgrade(req)) { if (server.upgrade(req)) {
return; return;
} }
return new Response("Upgrade failed", { status: 500 }); await Backend.postAnalytics(req, server);
return Response.redirect("/");
}, },
"/api/gc": async (req, server) => { "/api/gc": async () => {
gc(true) gc(true)
return new Response(gzipSync(JSON.stringify({ data: "triggered" })), { return Backend.Responses.ok();
headers: {
"Content-Type": "application/json",
"Cache-Control": "no-cache",
"Content-Encoding": "gzip",
}
})
},
"/api/script.js": async () => {
const req = await fetch("https://plausible.creations.works/js/script.js")
const script = await req.text()
return new Response(gzipSync(script), {
headers: {
"Content-Type": "application/javascript",
"Content-Encoding": "gzip",
"Cache-Control": "public, max-age=31536000",
}
})
},
"/api/script": async (req) => {
const request = new Request(req);
request.headers.delete('cookie');
return await fetch("https://plausible.creations.works/api/event", request);
}, },
"/api/headers": async (req) => { "/api/headers": async (req) => {
return new Response(gzipSync(JSON.stringify({ headers: req.headers })), { return Backend.Responses.json({ ...req.headers.toJSON() });
headers: {
"Content-Type": "application/json",
"Content-Encoding": "gzip",
"Cache-Control": "no-cache",
}
})
} }
}, },
fetch: async (request, server) => {
await Backend.postAnalytics(request, server);
return Response.redirect("/");
},
websocket: { websocket: {
idleTimeout: 1,
open: async (ws) => { open: async (ws) => {
ws.subscribe("lanyard"); ws.subscribe("lanyard");
ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true); ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true);
@ -178,91 +92,16 @@ const webserver = serve({
ws.send(JSON.stringify({ type: "echo", data: message }), true) ws.send(JSON.stringify({ type: "echo", data: message }), true)
} }
}, },
development, development: Backend.development,
port: 2056 port: 2056
}); });
const lanyardSocket = new WebSocket("wss://lanyard.creations.works/socket"); new Backend.Sockets.Hyperate((data) => {
heartrate = data;
server.publish("hyperate", JSON.stringify({ type: "hyperate", data: { hr: heartrate } }), true);
})
const setLanyard = (data: object) => { new Backend.Sockets.Lanyard((data) => {
lanyard = data; lanyard = data;
server.publish("lanyard", JSON.stringify({ type: "lanyard", data: lanyard }), true);
return webserver.publish("lanyard", JSON.stringify({ type: "lanyard", data }), true); });
}
lanyardSocket.onmessage = ({ data }) => {
data = JSON.parse(data);
switch (data.op) {
case 0: {
setLanyard(data.d)
break;
}
case 1: {
lanyardSocket.send(JSON.stringify({
op: 2,
d: {
subscribe_to_id: "1273447359417942128"
}
}))
break;
}
}
}
const hyperate = new WebSocket(
"wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9",
);
let hrTimeout: ReturnType<typeof setTimeout>;
const setHeartrate = async (hr: number) => {
heartrate = hr;
return webserver.publish("hyperate", JSON.stringify({ type: "hyperate", data: { hr } }), true);
}
const setHrInterval = () => {
hrTimeout = setTimeout(() => {
setHeartrate(0);
}, 6000);
};
hyperate.onopen = () => {
hyperate.send(
JSON.stringify({
topic: "hr:0BCA",
event: "phx_join",
payload: {},
ref: 0,
}),
);
setInterval(() => {
hyperate.send(
JSON.stringify({
topic: "phoenix",
event: "heartbeat",
payload: {},
ref: 0,
}),
);
}, 10000);
return setHrInterval();
};
hyperate.onmessage = ({ data }) => {
const { event, payload } = JSON.parse(data);
switch (event) {
case "hr_update": {
clearTimeout(hrTimeout);
setHrInterval();
setHeartrate(payload.hr);
break;
}
default: {
break;
}
}
};

View file

@ -15,7 +15,9 @@
"private": true, "private": true,
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"@speed-highlight/core": "^1.2.7",
"microlight": "^0.0.7", "microlight": "^0.0.7",
"reconnecting-websocket": "^4.4.0",
"tsx-dom": "^3.1.0" "tsx-dom": "^3.1.0"
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,17 +0,0 @@
import { Glob } from "bun";
const woff2 = new Glob("./*.woff2");
for await (const file of woff2.scan(".")) {
const font = Bun.file(file);
const name = font.name?.split("-")[1];
await Bun.write(`./${name}`, await font.arrayBuffer());
console.log(`Renamed ${file} to ${name}`);
await font.delete();
console.log(`Deleted original font file: ${file}`);
}
console.log("Done")

View file

@ -0,0 +1,88 @@
import ReconnectingWebSocket from 'reconnecting-websocket';
export default class {
private _socket: ReconnectingWebSocket;
private _keepAlive: NodeJS.Timeout | null;
private _interval: NodeJS.Timeout | null;
private _callback: (data: number) => void;
constructor(callback: (data: number) => void) {
this._socket = new ReconnectingWebSocket("wss://app.hyperate.io/socket/websocket?token=wv39nM6iyrNJulvpmMQrimYPIXy2dVrYRjkuHpbRapKT2VSh65ngDGHdCdCtmEN9")
this._keepAlive = null;
this._interval = null;
this._callback = callback;
this._socket.binaryType = "arraybuffer";
this._socket.onopen = () => {
console.log("Hyperate socket opened")
this._socket.send(
JSON.stringify({
topic: "hr:84aa0f",
event: "phx_join",
payload: {},
ref: 0,
}),
);
this._keepAlive = setInterval(() => {
this._socket.send(
JSON.stringify({
topic: "phoenix",
event: "heartbeat",
payload: {},
ref: 0,
}),
);
}, 10000);
}
this._socket.onmessage = ({ data }: MessageEvent) => {
data = JSON.parse(data);
switch (data.event) {
case "hr_update": {
this._callback(data.payload.hr);
this.heartbeat();
break;
}
}
}
this._socket.onerror = () => {
console.error("Hyperate socket error");
if (this._keepAlive) {
clearInterval(this._keepAlive);
this._keepAlive = null;
}
if (this._interval) {
clearInterval(this._interval);
this._interval = null;
}
}
this._socket.onclose = () => {
console.log("Hyperate socket closed");
if (this._keepAlive) {
clearInterval(this._keepAlive);
this._keepAlive = null;
}
if (this._interval) {
clearInterval(this._interval);
this._interval = null;
}
}
}
private heartbeat() {
if (this._interval) {
clearTimeout(this._interval);
this._interval = null;
}
this._interval = setTimeout(() => {
this._callback(0);
}, 6000);
}
}

View file

@ -0,0 +1,61 @@
import ReconnectingWebSocket from 'reconnecting-websocket';
export default class {
private _socket: ReconnectingWebSocket;
private _keepAlive: NodeJS.Timeout | null;
private _callback: (data: { [key: string]: string }) => void;
constructor(callback: (data: { [key: string]: string }) => void) {
this._socket = new ReconnectingWebSocket("wss://lanyard.creations.works/socket")
this._keepAlive = null;
this._callback = callback;
this._socket.binaryType = "arraybuffer";
this._socket.onopen = () => {
console.log("Lanyard socket opened")
}
this._socket.onmessage = ({ data }: MessageEvent) => {
data = JSON.parse(data);
switch (data.op) {
case 0: {
this._callback(data.d)
break;
}
case 1: {
this._socket.send(JSON.stringify({
op: 2,
d: {
subscribe_to_id: "1273447359417942128"
}
}))
this._keepAlive = setInterval(() => {
this._socket.send(JSON.stringify({
op: 3
}))
}, data.d.heartbeat_interval)
break;
}
}
}
this._socket.onerror = () => {
console.error("Lanyard socket error");
if (this._keepAlive) {
clearInterval(this._keepAlive);
this._keepAlive = null;
}
}
this._socket.onclose = () => {
console.log("Lanyard socket closed");
if (this._keepAlive) {
clearInterval(this._keepAlive);
this._keepAlive = null;
}
}
}
}

74
src/back/index.ts Normal file
View file

@ -0,0 +1,74 @@
import Hyperate from "./Sockets/Hyperate";
import Lanyard from "./Sockets/Lanyard";
const development = process.env.NODE_ENV === "development";
const build = async () => {
return await Bun.build({
entrypoints: ['./src/front/index.html'],
outdir: './dist',
minify: !development,
sourcemap: (development ? "inline" : "none"),
splitting: true,
publicPath: "/assets/",
})
}
const respOptions = {
headers: {
"Content-Type": "application/json",
"Cache-Control": "no-cache",
"Content-Encoding": "gzip",
}
}
const okResp = new Response(Bun.gzipSync(JSON.stringify({ data: "ok" })), respOptions)
const Responses = {
ok: () => {
return okResp.clone();
},
json: (data: { [key: string]: string }) => {
return new Response(Bun.gzipSync(JSON.stringify(data)), respOptions);
},
file: async (file: Bun.BunFile) => {
return new Response(Bun.gzipSync(await file.arrayBuffer()), {
headers: {
"Content-Type": file.type,
"Cache-Control": "public, max-age=31536000",
"Content-Encoding": "gzip",
}
});
}
}
const postAnalytics = async (req: Request | Bun.BunRequest, server: Bun.Server) => {
return await fetch("https://plausible.creations.works/api/event", {
method: "POST",
headers: {
"Content-Type": "application/json",
"User-Agent": req.headers.get("user-agent") || "",
"X-Forwarded-For": String(
req.headers.get("CF-Connecting-IP") ||
req.headers.get("X-Real-IP") ||
req.headers.get("X-Forwarded-For")?.split(",")[0] ||
(typeof server.requestIP(req) === "string" ? server.requestIP(req) : (server.requestIP(req)?.address || ""))
),
},
body: JSON.stringify({
domain: "ipv4.army",
name: "pageview",
url: req.url,
referrer: req.headers.get("referer") || "",
})
})
}
export default {
Sockets: {
Hyperate,
Lanyard
},
Responses,
build,
development,
postAnalytics,
};

View file

@ -1,40 +0,0 @@
import { createRef } from "tsx-dom";
import microlight from "microlight";
import socket from "../../Socket";
const statusTypes: { [key: string]: string } = {
online: "green",
idle: "yellow",
dnd: "red",
invisible: "inherent",
offline: "inherent",
}
const activityTypes: { [key: number]: string } = {
0: "Playing",
1: "Streaming",
2: "Listening to",
3: "Watching",
4: "Custom",
5: "Competing in",
}
export default () => {
const paragraph = createRef<HTMLParagraphElement>();
socket.addEventListener('lanyard', (event: Event) => {
const lanyard = (event as CustomEvent).detail;
if (paragraph.current) {
paragraph.current.style = `--status-color: ${statusTypes[lanyard.discord_status]};`;
paragraph.current.innerText = JSON.stringify({
status: lanyard.discord_status,
activities: lanyard.activities.map((act: { type: number, name: string }) => { return `${activityTypes[act.type]} ${act.name}` }),
}, null, 1);
}
microlight.reset();
});
return <div>
<p class="microlight" ref={paragraph}>{JSON.stringify({})}</p>
</div>;
}

View file

@ -4,7 +4,7 @@
.scanlines:before, .scanlines:before,
.scanlines:after { .scanlines:after {
display: block; display: inherit;
pointer-events: none; pointer-events: none;
content: ""; content: "";
position: absolute; position: absolute;
@ -28,8 +28,8 @@
background: linear-gradient(to bottom, background: linear-gradient(to bottom,
transparent 50%, transparent 50%,
rgba(0, 0, 0, 0.3) 51%); rgba(0, 0, 0, 0.3) 51%);
background-size: 100% 4px; background-size: 100% 6px;
animation: scanlines 1s steps(60) infinite; animation: scanlines 2s steps(30) infinite;
} }
/* ANIMATE UNIQUE SCANLINE */ /* ANIMATE UNIQUE SCANLINE */
@ -45,15 +45,15 @@
} }
} }
div { span.shj-syn-str:nth-child(2) {
margin: 0; color: var(--status-color, rgba(150, 150, 150, 0.1));
padding: 0;
} }
div.scanlines { .shj-numbers {
position: absolute; padding: 0px;
} }
.microlight>span:nth-child(6) { .shj-lang-json {
color: var(--status-color); padding: 0px;
background-color: transparent;
} }

View file

@ -2,9 +2,9 @@ import Lanyard from './components/Lanyard';
import Hyperate from './components/Hyperate'; import Hyperate from './components/Hyperate';
export default () => { export default () => {
return <div> return <div class="app">
<p>seth&gt; cat ./about.txt</p> <p>seth&gt; cat ./about.txt</p>
<p>A Dedicated Backend Developer, with a passion for high-fidelity audio, gaming, and web development.</p> <p>A Dedicated Backend Developer,<br />with a passion for high-fidelity audio,<br />gaming, and web development.</p>
<p>seth&gt; curl /tmp/discord-ipc</p> <p>seth&gt; curl /tmp/discord-ipc</p>
<p><Lanyard /></p> <p><Lanyard /></p>

View file

@ -19,12 +19,24 @@ class Socket extends EventTarget {
this.emitHyperate(data.hr); this.emitHyperate(data.hr);
break; break;
} }
case "echo": {
console.log("Echo: ", data);
break;
}
default: {
console.error("Unknown message type: ", type, data);
break;
}
} }
}; };
this._socket.onclose = () => {
location.reload();
};
setInterval(() => { setInterval(() => {
this._socket.send("ping"); this._socket.send("ping");
}, 10000); }, 30 * 1000);
} }
emitLanyard(lanyard: object) { emitLanyard(lanyard: object) {

View file

@ -1,5 +1,4 @@
import { createRef } from "tsx-dom"; import { createRef } from "tsx-dom";
import microlight from "microlight";
import socket from "../../Socket"; import socket from "../../Socket";
@ -11,9 +10,8 @@ export default () => {
if (paragraph.current) { if (paragraph.current) {
paragraph.current.innerText = `${heartRate} BPM`; paragraph.current.innerText = `${heartRate} BPM`;
} }
microlight.reset();
}); });
return <div> return <div>
<p class="microlight" ref={paragraph}>0 BPM</p> <p ref={paragraph}>0 BPM</p>
</div>; </div>;
} }

View file

@ -0,0 +1,59 @@
import { createRef } from "tsx-dom";
import { highlightAll } from "@speed-highlight/core";
import socket from "../../Socket";
const statusTypes: { [key: string]: string } = {
online: "rgb(0, 150, 0)",
idle: "rgb(150, 150, 0)",
dnd: "rgb(150, 0, 0)",
offline: "rgb(150, 150, 150)",
}
const gradientTypes: { [key: string]: string } = {
online: "rgba(0, 150, 0, 0.1)",
idle: "rgba(150, 150, 0, 0.1)",
dnd: "rgba(150, 0, 0, 0.1)",
offline: "rgba(150, 150, 150, 0.1)",
}
const activityTypes: { [key: number]: string } = {
0: "Playing",
1: "Streaming",
2: "Listening to",
3: "Watching",
4: "Custom Status",
5: "Competing in",
}
const stringify = (data: { [key: string]: string }) => {
return JSON.stringify(data, null, 2)
}
export default () => {
const code = createRef<HTMLDivElement>();
socket.addEventListener('lanyard', (event: Event) => {
const lanyard = (event as CustomEvent).detail;
document.body.style = `--status-color: ${statusTypes[lanyard.discord_status]}; --gradient-color: ${gradientTypes[lanyard.discord_status]};`;
if (code.current) {
code.current.innerHTML = stringify({
status: lanyard.discord_status,
activities: lanyard.activities.map((act: {
type: number, name: string, details: string, state: string
}) => {
return [
... new Set([
activityTypes[act.type],
act.name,
act.details,
act.state
])
].filter(n => n)
}),
});
}
highlightAll();
});
return <div class="shj-lang-json" ref={code}>{"{}"}</div>
}

20
src/front/index.css Normal file
View file

@ -0,0 +1,20 @@
@import "../../node_modules/@speed-highlight/core/dist/themes/dark.css";
@import "./App.css";
html,
head,
body {
margin: 0;
padding: 0;
font: 2vh monospace;
height: 100vh;
width: 100vw;
}
body {
color: #DEDEDE;
text-shadow: 0 0 5px #C8C8C8;
background: radial-gradient(at bottom right, var(--gradient-color, rgba(150, 150, 150, 0.1)) 0%, rgba(0, 0, 0, 1) 100%);
display: flex;
}

View file

@ -4,7 +4,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="theme-color" content="#1a1d1f"> <meta name="theme-color" content="#000000">
<meta name="description" <meta name="description"
content="A Dedicated Backend Developer, with a passion for high-fidelity audio, gaming, and web development."> content="A Dedicated Backend Developer, with a passion for high-fidelity audio, gaming, and web development.">
<meta name="keywords" content="Seth, IPv4, Army, Seth@IPv4, web development, audio, gaming"> <meta name="keywords" content="Seth, IPv4, Army, Seth@IPv4, web development, audio, gaming">
@ -13,12 +13,10 @@
<link rel="icon" href="/public/favicon.svg" /> <link rel="icon" href="/public/favicon.svg" />
<meta name="color-scheme" content="dark" /> <meta name="color-scheme" content="dark" />
<link rel="stylesheet" href="index.css" /> <link rel="stylesheet" href="index.css" />
<style id="font"></style>
</head> </head>
<body class="scanlines"> <body class="scanlines">
<script src="index.tsx"></script> <script src="index.tsx"></script>
<script defer data-domain="yourdomain.com" data-api="/api/script" src="https://ipv4.army/api/script.js"></script>
</body> </body>
</html> </html>

8
src/front/index.tsx Normal file
View file

@ -0,0 +1,8 @@
import "tsx-dom";
import App from './App';
document.body.appendChild(<App />);
// You're garbage, let me collect you.
fetch("/api/gc")

View file

@ -1,18 +0,0 @@
@import "./App.css";
html,
head,
body {
margin: 0;
padding: 0;
font-family: 'Circular Std', sans-serif;
height: 100vh;
width: 100vw;
}
body {
color: #DEDEDE;
font: 2vh Inconsolata, monospace;
text-shadow: 0 0 5px #C8C8C8;
background: radial-gradient(at bottom right, rgba(0, 150, 0, 0.1) 0%, rgba(0, 0, 0, 1) 100%);
}

View file

@ -1,74 +0,0 @@
import "tsx-dom";
import App from './App';
const font = document.getElementById("font")
if (font) {
font.innerText = `@font-face {
font-family: 'Circular Std';
src: url('/public/font/Black.woff2') format('woff2');
font-weight: black;
font-style: normal;
font-display: swap
}
@font-face {
font-family: 'Circular Std';
src: url('/public/font/BlackItalic.woff2') format('woff2');
font-weight: black;
font-style: italic;
font-display: swap
}
@font-face {
font-family: 'Circular Std';
src: url('/public/font/Bold.woff2') format('woff2');
font-weight: bold;
font-style: normal;
font-display: swap
}
@font-face {
font-family: 'Circular Std';
src: url('/public/font/BoldItalic.woff2') format('woff2');
font-weight: bold;
font-style: italic;
font-display: swap
}
@font-face {
font-family: 'Circular Std';
src: url('/public/font/Book.woff2') format('woff2');
font-weight: normal;
font-style: normal;
font-display: swap
}
@font-face {
font-family: 'Circular Std';
src: url('/public/font/BookItalic.woff2') format('woff2');
font-weight: normal;
font-style: italic;
font-display: swap
}
@font-face {
font-family: 'Circular Std';
src: url('/public/font/Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap
}
@font-face {
font-family: 'Circular Std';
src: url('/public/font/MediumItalic.woff2') format('woff2');
font-weight: 500;
font-style: italic;
font-display: swap
}`
}
document.body.appendChild(<App />);
// You're garbage, let me collect you.
fetch("/api/gc")