mirror of
https://github.com/spacebarchat/server.git
synced 2026-06-08 06:31:46 +00:00
prep for presence
This commit is contained in:
@@ -18,8 +18,8 @@
|
||||
|
||||
import { Capabilities, CLOSECODES, OPCODES, Payload, Send, setupListener, WebSocket } from "@spacebar/gateway";
|
||||
import {
|
||||
arrayGroupBy,
|
||||
Application,
|
||||
arrayGroupBy,
|
||||
Channel,
|
||||
checkToken,
|
||||
Config,
|
||||
@@ -60,8 +60,8 @@ import {
|
||||
import { check } from "./instanceOf";
|
||||
import { In, Not } from "typeorm";
|
||||
import { PreloadedUserSettings } from "discord-protos";
|
||||
import { ChannelType, DefaultUserGuildSettings, DMChannel, IdentifySchema, PrivateUserProjection, PublicUser, PublicUserProjection } from "@spacebar/schemas";
|
||||
import { randomString } from "@spacebar/api*";
|
||||
import { ChannelType, DefaultUserGuildSettings, DMChannel, IdentifySchema, PrivateUserProjection, PublicUser, PublicUserProjection, RelationshipType } from "@spacebar/schemas";
|
||||
import { randomString } from "@spacebar/api";
|
||||
|
||||
// TODO: user sharding
|
||||
// TODO: check privileged intents, if defined in the config
|
||||
@@ -193,7 +193,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
|
||||
event: "PRESENCE_UPDATE",
|
||||
data: {
|
||||
user: tokenData.user.toPublicUser(),
|
||||
status: this.session.status,
|
||||
status: this.session.getPublicStatus(),
|
||||
client_status: this.session.client_status,
|
||||
activities: this.session.activities,
|
||||
},
|
||||
@@ -878,7 +878,7 @@ export async function onIdentify(this: WebSocket, data: Payload) {
|
||||
process.env.LOG_GATEWAY_TRACES ? JSON.stringify(d._trace, null, 2) : "",
|
||||
);
|
||||
|
||||
// actually send presence updates
|
||||
// actually send presence updates - not using distributePresenceUpdate because we already have all of the data at hand
|
||||
if (presenceUpdateEventData) {
|
||||
for (const rel of d.relationships ?? []) {
|
||||
await emitEvent({
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Session } from "@spacebar/util";
|
||||
|
||||
export function genSessionId() {
|
||||
return genRanHex(32);
|
||||
}
|
||||
@@ -29,20 +27,3 @@ export function genVoiceToken() {
|
||||
function genRanHex(size: number) {
|
||||
return [...Array(size)].map(() => Math.floor(Math.random() * 16).toString(16)).join("");
|
||||
}
|
||||
|
||||
export function getMostRelevantSession(sessions: Session[]) {
|
||||
const statusMap = {
|
||||
online: 0,
|
||||
idle: 1,
|
||||
dnd: 2,
|
||||
invisible: 3,
|
||||
offline: 4,
|
||||
unknown: 5,
|
||||
};
|
||||
// sort sessions by relevance
|
||||
sessions = sessions.sort((a, b) => {
|
||||
return statusMap[a.status] - statusMap[b.status] + ((a.activities?.length ?? 0) - (b.activities?.length ?? 0)) * 2;
|
||||
});
|
||||
|
||||
return sessions[0];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Spacebar: A FOSS re-implementation and extension of the Discord.com backend.
|
||||
Copyright (C) 2026 Spacebar and Spacebar Contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { emitEvent, Member, PresenceUpdateEvent, Recipient, Relationship, Session } from "@spacebar/util";
|
||||
import { RelationshipType } from "@spacebar/schemas";
|
||||
import { Not } from "typeorm";
|
||||
|
||||
export function getMostRelevantSession(sessions: Session[]) {
|
||||
const statusMap = {
|
||||
online: 0,
|
||||
idle: 1,
|
||||
dnd: 2,
|
||||
invisible: 3,
|
||||
offline: 4,
|
||||
unknown: 5,
|
||||
};
|
||||
// sort sessions by relevance
|
||||
sessions = sessions.sort((a, b) => {
|
||||
return statusMap[a.status] - statusMap[b.status] + ((a.activities?.length ?? 0) - (b.activities?.length ?? 0)) * 2;
|
||||
});
|
||||
|
||||
return sessions[0];
|
||||
}
|
||||
|
||||
export async function distributePresenceUpdate(userId: string, data: PresenceUpdateEvent) {
|
||||
let relationships: Relationship[] | undefined = await Relationship.find({
|
||||
where: { from_id: userId, type: RelationshipType.friends },
|
||||
select: { from_id: true, to_id: true },
|
||||
});
|
||||
for (const rel of relationships)
|
||||
await emitEvent({
|
||||
...data,
|
||||
user_id: rel.to_id,
|
||||
});
|
||||
// noinspection JSUnusedAssignment - drop array ref
|
||||
relationships = undefined;
|
||||
|
||||
let memberGuildIds: string[] | undefined = (
|
||||
await Member.find({
|
||||
where: { id: userId },
|
||||
select: { guild_id: true },
|
||||
})
|
||||
).map((x) => x.guild_id);
|
||||
for (const rel of memberGuildIds)
|
||||
await emitEvent({
|
||||
...data,
|
||||
guild_id: rel,
|
||||
});
|
||||
// noinspection JSUnusedAssignment - drop array ref
|
||||
memberGuildIds = undefined;
|
||||
|
||||
const recipients = await Recipient.find({ where: { user_id: userId, closed: false }, relations: { channel: true } });
|
||||
for (const recipient of recipients) {
|
||||
const otherRecipients = await Recipient.find({ where: { user_id: Not(userId), channel_id: recipient.channel_id } });
|
||||
for (const otherRcpt of otherRecipients) {
|
||||
if (otherRcpt.closed) continue;
|
||||
await emitEvent({
|
||||
...data,
|
||||
user_id: otherRcpt.user_id,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user