Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONTRIBUTING.MD
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Welcome to Spacebar, if you've made it here, I'm guessing you're looking to cont
A good place to start would be over at the issues tab, though https://docs.spacebar.chat/contributing/server/missingroute/
may also be a good indicator for things that are remaining.

If you find yourself working on something, or want to discuss particular issues, feel free to drop by our developers guild (<a href="https://fermi.chat/invite/developers?instance=spacebar.chat">
<img src="https://api.old.server.spacebar.chat/api/guilds/1471300112201604309/shield.svg" />
If you find yourself working on something, or want to discuss particular issues, feel free to drop by our developers guild (<a href="https://sbar.top/i/developers?instance=spacebar.chat">
<img src="https://api.rory.server.spacebar.chat/api/guilds/1471300112201604309/shield.svg" />
</a>)

Keep in mind that we do, under no circumstances, accept AI-generated, AI-assisted, or otherwise machine-generated contributions, for legal reasons.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
<a href="https://matrix.to/#/#spacebar:rory.gay">
<img src="https://img.shields.io/matrix/spacebar%3Arory.gay?server_fqdn=matrix.rory.gay&fetchMode=summary&logo=matrix&logoColor=fffffff&label=Matrix" />
</a>
<a href="https://fermi.chat/invite/spacebar?instance=spacebar.chat">
<img src="https://api.old.server.spacebar.chat/api/guilds/1006649183970562092/shield.svg" />
<a href="https://sbar.top/i/spacebar?instance=spacebar.chat">
<img src="https://api.rory.server.spacebar.chat/api/guilds/1006649183970562092/shield.svg" />
</a>
<a href="https://discord.gg/ZrnGQP6p3d">
<img src="https://img.shields.io/discord/806142446094385153?color=7489d5&logo=discord&logoColor=ffffff&label=Discord" />
Expand Down Expand Up @@ -48,4 +48,4 @@ And with documentation on how to set up your own server [here](https://docs.spac
You _should_ be able to use any client designed for Discord.com to connect to a Spacebar instance.
However, some incompatibilities still exist between Spacebar and Discord. For this reason, not every client will connect.
We recommend using [Fermo](https://fermo.sovr.top/login?instance=spacebar.chat) as a solid starting point on your adventure in the SpaceBar!
You can explore other clients with the [Spacebar Explorer](https://spacebar-explorer.sovr.top/clients).
You can explore other clients with the [Spacebar Explorer](https://sbar.top/clients).
9 changes: 4 additions & 5 deletions src/gateway/util/Send.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { Payload, WebSocket } from "@spacebar/gateway";
import fs from "node:fs/promises";
import path from "node:path";

import { JSONReplacer } from "@spacebar/util";
import { JSONReplacer, cleanCircularRefs } from "@spacebar/util";
import * as erlpack from "harmony-erlpack";

// don't care
Expand Down Expand Up @@ -54,10 +54,9 @@ export async function Send(socket: WebSocket, data: Payload) {
// Erlpack doesn't like Date objects, encodes them as {}
data = recurseJsonReplace(data);
buffer = Buffer.from(erlpack.pack(data));
}
// TODO: encode circular object
else if (socket.encoding === "json") buffer = JSON.stringify(data, JSONReplacer);
else return;
} else if (socket.encoding === "json") {
buffer = JSON.stringify(cleanCircularRefs(data), JSONReplacer);
} else return;

// TODO: compression
if (socket.compress === "zlib-stream") {
Expand Down
25 changes: 25 additions & 0 deletions src/util/util/JSON.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,28 @@ export function JSONReplacer(this: { [key: string]: unknown }, key: string, valu

return value;
}

/**
* Walk an object tree and null out circular references in-place,
* while preserving shared (non-circular) references.
*/
export function cleanCircularRefs<T>(data: T): T {
const ancestors = new Set<object>();
function walk(val: unknown): unknown {
if (val === null || typeof val !== "object") return val;
if (ancestors.has(val)) return null;
ancestors.add(val);
if (Array.isArray(val)) {
for (let i = 0; i < val.length; i++) {
val[i] = walk(val[i]) as (typeof val)[number];
}
} else {
for (const key of Object.keys(val as Record<string, unknown>)) {
(val as Record<string, unknown>)[key] = walk((val as Record<string, unknown>)[key]);
}
}
ancestors.delete(val);
return val;
}
return walk(data) as T;
}
8 changes: 4 additions & 4 deletions src/webrtc/util/Send.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { JSONReplacer } from "@spacebar/util";
import { JSONReplacer, cleanCircularRefs } from "@spacebar/util";
import { VoicePayload } from "./Constants";
import { WebRtcWebSocket } from "./WebRtcWebSocket";

Expand All @@ -7,9 +7,9 @@ export function Send(socket: WebRtcWebSocket, data: VoicePayload) {

let buffer: Buffer | string;

// TODO: encode circular object
if (socket.encoding === "json") buffer = JSON.stringify(data, JSONReplacer);
else return;
if (socket.encoding === "json") {
buffer = JSON.stringify(cleanCircularRefs(data), JSONReplacer);
} else return;

return new Promise((res, rej) => {
if (socket.readyState !== 1) {
Expand Down
Loading